From 60496c9e99e281ca161e355608dbea7edf1eff7d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Sep 2012 14:00:01 +0200 Subject: vf_lavc: fix compilation with latest libav Remove a pointless and broken check for avctx->codec->encode. 1) The check does not test for anything useful. 2) AVCodecContext.encode is a private field and is not supposed to be accessed from outside of lavc. 2a) AVCodecContext.encode does not exist anymore in latest libavcodec, so this block fails to build. --- libmpcodecs/vf_lavc.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'libmpcodecs') diff --git a/libmpcodecs/vf_lavc.c b/libmpcodecs/vf_lavc.c index b2c1dd756d..65e93a16cc 100644 --- a/libmpcodecs/vf_lavc.c +++ b/libmpcodecs/vf_lavc.c @@ -76,11 +76,6 @@ static int config(struct vf_instance *vf, return 0; } - if (lavc_venc_context.codec->encode == NULL) { - mp_msg(MSGT_VFILTER,MSGL_ERR,"avcodec init failed (ctx->codec->encode == NULL)!\n"); - return 0; - } - return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_MPEGPES); } -- cgit v1.2.3 From e5afc1f405d0c45a4d712807aa8f30fffc71c6d6 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 2 Oct 2012 14:14:07 +0200 Subject: Remove useless video filters Most of these have very limited actual use, or are even entirely useless. They only serve to bloat the codebase and to make life harder. Drowning users in tons of barely useful filters isn't exactly helpful either. Some of these filters were redundant or marked as obsolete. The dlopen and lua (to be added soon) video filters provide ways to add custom filters. Detailed listing for each filter with reasons (with contributions from divVerent and lachs0r): 1bpp: Replaced by "scale". 2xsai: Pixel art scaling algorithm, useless with lossy video. blackframe: Not very useful. Apparently one use is combining it with scripts, that pass the bmovl: Weirdly complex and insane (using FIFO commands), questionable use. cropdetect: Only sort-of useful when used with scripts, and then it will be very fragile. It's probably better to use the dlopen rectangle filter, or to implement the common use-case in a better way. decimate: Not needed/useful with modern video codecs, is an encoding-only filter. denoise3d: "hqdn3d" is better. detc: Some of the worse deteleciners. dint: Useless, actually crashes. (On an assert in vf.c that is disabled by default in mplayer-svn.) dvbscale: Not even practical, and the same effect can be achieved through other means. eq: Worse/older version of eq2. field: Limited use, available as dlopen filter. fil: Quoting the manpage: This filter is very similar to the il filter but much faster, the main disadvantage is that it does not always work. Especially if combined with other filters it may produce randomly messed up images, so be happy if it works but do not complain if it does not for your combination of filters. filmdint: Kind of redundant with pullup, and slightly worse. fixpts: Never useful. (Most if not all filters have been fixed for PTS.) framestep: Questionable use. For things like creating thumbnails, ffmpeg or --sstep should be used. geq: Limited use, will be redundant with the "lua" filter. halfpack: Useless, probably redundant with "scale". harddup: Useless. hue: Most VOs support this. il: Useless. ivtc: Another of the worse deteleciners. kerndeint: A bad deinterlacer. lavc: For DVB output devices. We removed that support. lavcdeint: A bad deinterlacer, was already deprecated. Still available as --vf=pp=fd. mcdeint: A broken deinterlacer that uses lavc internals. ow: Very slow, barely any quality benefit over "hqdn3d". palette: Done by "scale". perspective: Files with incorrect perspective are extremely rare. About the only real-world use for this is keystone correction, which is usually done in hardware by the projector or by graphics drivers/compositors. pp7: Another useless postprocessing filter with bad and complicated code. Use libpostprocess with "pp" instead. qp: Useless. remove-logo: Redundant with delogo, which is better and more practical. rgbtest: Useless. sab, smartblur, boxblur: Blur filters, redundant to "unsharp". softskip: Does nothing. spp, fspp, uspp: Useless postprocessing filters. "spp" needs ffmpeg internals. "fspp" is the optimized version of the "spp" filter (???), while "uspp" is the slow version (????). Use libpostprocess with "pp" instead. telecine: Evil and useless. Available as dlopen filter for testing purposes. test: Useless. tfields: Useless, probably. tile: Questionable use. Available as dlopen filter. tinterlace: Evil and useless. yuvcsp: Probably useless. yvu9: Redundant with "scale". Also remove the following left-over files: vd_null.c, vqf.h --- DOCS/man/en/vf.rst | 652 +------------ Makefile | 52 -- configure | 10 - libmpcodecs/cmmx.h | 202 ---- libmpcodecs/vd_null.c | 56 -- libmpcodecs/vf.c | 99 +- libmpcodecs/vf_1bpp.c | 207 ----- libmpcodecs/vf_2xsai.c | 336 ------- libmpcodecs/vf_blackframe.c | 148 --- libmpcodecs/vf_bmovl.c | 496 ---------- libmpcodecs/vf_boxblur.c | 214 ----- libmpcodecs/vf_cropdetect.c | 200 ---- libmpcodecs/vf_decimate.c | 198 ---- libmpcodecs/vf_denoise3d.c | 268 ------ libmpcodecs/vf_detc.c | 458 --------- libmpcodecs/vf_dint.c | 214 ----- libmpcodecs/vf_dvbscale.c | 67 -- libmpcodecs/vf_eq.c | 258 ------ libmpcodecs/vf_field.c | 89 -- libmpcodecs/vf_fil.c | 116 --- libmpcodecs/vf_filmdint.c | 1442 ---------------------------- libmpcodecs/vf_fixpts.c | 136 --- libmpcodecs/vf_framestep.c | 203 ---- libmpcodecs/vf_fspp.c | 2112 ------------------------------------------ libmpcodecs/vf_geq.c | 197 ---- libmpcodecs/vf_halfpack.c | 254 ----- libmpcodecs/vf_harddup.c | 92 -- libmpcodecs/vf_hue.c | 200 ---- libmpcodecs/vf_il.c | 148 --- libmpcodecs/vf_ivtc.c | 555 ----------- libmpcodecs/vf_kerndeint.c | 345 ------- libmpcodecs/vf_lavc.c | 173 ---- libmpcodecs/vf_lavcdeint.c | 188 ---- libmpcodecs/vf_mcdeint.c | 330 ------- libmpcodecs/vf_ow.c | 322 ------- libmpcodecs/vf_palette.c | 234 ----- libmpcodecs/vf_perspective.c | 341 ------- libmpcodecs/vf_pp7.c | 489 ---------- libmpcodecs/vf_qp.c | 177 ---- libmpcodecs/vf_remove_logo.c | 908 ------------------ libmpcodecs/vf_rgbtest.c | 171 ---- libmpcodecs/vf_sab.c | 292 ------ libmpcodecs/vf_smartblur.c | 236 ----- libmpcodecs/vf_softskip.c | 102 -- libmpcodecs/vf_spp.c | 612 ------------ libmpcodecs/vf_telecine.c | 190 ---- libmpcodecs/vf_test.c | 332 ------- libmpcodecs/vf_tfields.c | 476 ---------- libmpcodecs/vf_tile.c | 332 ------- libmpcodecs/vf_tinterlace.c | 235 ----- libmpcodecs/vf_uspp.c | 384 -------- libmpcodecs/vf_yuvcsp.c | 120 --- libmpcodecs/vf_yvu9.c | 104 --- libmpcodecs/vqf.h | 228 ----- 54 files changed, 4 insertions(+), 16996 deletions(-) delete mode 100644 libmpcodecs/cmmx.h delete mode 100644 libmpcodecs/vd_null.c delete mode 100644 libmpcodecs/vf_1bpp.c delete mode 100644 libmpcodecs/vf_2xsai.c delete mode 100644 libmpcodecs/vf_blackframe.c delete mode 100644 libmpcodecs/vf_bmovl.c delete mode 100644 libmpcodecs/vf_boxblur.c delete mode 100644 libmpcodecs/vf_cropdetect.c delete mode 100644 libmpcodecs/vf_decimate.c delete mode 100644 libmpcodecs/vf_denoise3d.c delete mode 100644 libmpcodecs/vf_detc.c delete mode 100644 libmpcodecs/vf_dint.c delete mode 100644 libmpcodecs/vf_dvbscale.c delete mode 100644 libmpcodecs/vf_eq.c delete mode 100644 libmpcodecs/vf_field.c delete mode 100644 libmpcodecs/vf_fil.c delete mode 100644 libmpcodecs/vf_filmdint.c delete mode 100644 libmpcodecs/vf_fixpts.c delete mode 100644 libmpcodecs/vf_framestep.c delete mode 100644 libmpcodecs/vf_fspp.c delete mode 100644 libmpcodecs/vf_geq.c delete mode 100644 libmpcodecs/vf_halfpack.c delete mode 100644 libmpcodecs/vf_harddup.c delete mode 100644 libmpcodecs/vf_hue.c delete mode 100644 libmpcodecs/vf_il.c delete mode 100644 libmpcodecs/vf_ivtc.c delete mode 100644 libmpcodecs/vf_kerndeint.c delete mode 100644 libmpcodecs/vf_lavc.c delete mode 100644 libmpcodecs/vf_lavcdeint.c delete mode 100644 libmpcodecs/vf_mcdeint.c delete mode 100644 libmpcodecs/vf_ow.c delete mode 100644 libmpcodecs/vf_palette.c delete mode 100644 libmpcodecs/vf_perspective.c delete mode 100644 libmpcodecs/vf_pp7.c delete mode 100644 libmpcodecs/vf_qp.c delete mode 100644 libmpcodecs/vf_remove_logo.c delete mode 100644 libmpcodecs/vf_rgbtest.c delete mode 100644 libmpcodecs/vf_sab.c delete mode 100644 libmpcodecs/vf_smartblur.c delete mode 100644 libmpcodecs/vf_softskip.c delete mode 100644 libmpcodecs/vf_spp.c delete mode 100644 libmpcodecs/vf_telecine.c delete mode 100644 libmpcodecs/vf_test.c delete mode 100644 libmpcodecs/vf_tfields.c delete mode 100644 libmpcodecs/vf_tile.c delete mode 100644 libmpcodecs/vf_tinterlace.c delete mode 100644 libmpcodecs/vf_uspp.c delete mode 100644 libmpcodecs/vf_yuvcsp.c delete mode 100644 libmpcodecs/vf_yvu9.c delete mode 100644 libmpcodecs/vqf.h (limited to 'libmpcodecs') diff --git a/DOCS/man/en/vf.rst b/DOCS/man/en/vf.rst index 434c2faec3..d46bd5bc06 100644 --- a/DOCS/man/en/vf.rst +++ b/DOCS/man/en/vf.rst @@ -217,17 +217,6 @@ dsize[=aspect|w:h:aspect-method:r] Rounds up to make both width and height divisible by (default: 1). -yvu9 - Forces software YVU9 to YV12 colorspace conversion. Deprecated in favor of - the software scaler. - -yuvcsp - Clamps YUV color values to the CCIR 601 range without doing real - conversion. - -palette - RGB/BGR 8 -> 15/16/24/32bpp colorspace conversion using palette. - format[=fourcc[:outfourcc]] Restricts the colorspace for the next filter without doing any conversion. Use together with the scale filter for a real conversion. @@ -391,132 +380,6 @@ pp[=filter1[:option1[:option2...]]/[-]filter2...] Horizontal deblocking on luminance only, and switch vertical deblocking on or off automatically depending on available CPU time. -spp[=quality[:qp[:mode]]] - Simple postprocessing filter that compresses and decompresses the image at - several (or - in the case of quality level 6 - all) shifts and averages - the results. - - - 0-6 (default: 3) - - - Force quantization parameter (default: 0, use QP from video). - - - - :0: hard thresholding (default) - :1: soft thresholding (better deringing, but blurrier) - :4: like 0, but also use B-frames' QP (may cause flicker) - :5: like 1, but also use B-frames' QP (may cause flicker) - -uspp[=quality[:qp]] - Ultra simple & slow postprocessing filter that compresses and decompresses - the image at several (or - in the case of quality level 8 - all) shifts - and averages the results. - - The way this differs from the behavior of spp is that uspp actually - encodes & decodes each case with libavcodec Snow, whereas spp uses a - simplified intra only 8x8 DCT similar to MJPEG. - - - 0-8 (default: 3) - - - Force quantization parameter (default: 0, use QP from video). - -fspp[=quality[:qp[:strength[:bframes]]]] - faster version of the simple postprocessing filter - - - 4-5 (equivalent to spp; default: 4) - - - Force quantization parameter (default: 0, use QP from video). - - <-15-32> - Filter strength, lower values mean more details but also more - artifacts, while higher values make the image smoother but also - blurrier (default: 0 - PSNR optimal). - - - 0: do not use QP from B-frames (default) - 1: use QP from B-frames too (may cause flicker) - -pp7[=qp[:mode]] - Variant of the spp filter, similar to spp=6 with 7 point DCT where only - the center sample is used after IDCT. - - - Force quantization parameter (default: 0, use QP from video). - - - :0: hard thresholding - :1: soft thresholding (better deringing, but blurrier) - :2: medium thresholding (default, good results) - -qp=equation - quantization parameter (QP) change filter - - - some equation like ``2+2*sin(PI*qp)`` - -geq=equation - generic equation change filter - - - Some equation, e.g. ``p(W-X\,Y)`` to flip the image horizontally. You - can use whitespace to make the equation more readable. There are a - couple of constants that can be used in the equation: - - :PI: the number pi - :E: the number e - :X / Y: the coordinates of the current sample - :W / H: width and height of the image - :SW / SH: width/height scale depending on the currently filtered plane, - e.g. 1,1 and 0.5,0.5 for YUV 4:2:0. - :p(x,y): returns the value of the pixel at location x/y of the current - plane. - -test - Generate various test patterns. - -rgbtest[=width:height] - Generate an RGB test pattern useful for detecting RGB vs BGR issues. You - should see a red, green and blue stripe from top to bottom. - - - Desired width of generated image (default: 0). 0 means width of input - image. - - - Desired height of generated image (default: 0). 0 means height of - input image. - -lavc[=quality:fps] - Fast software YV12 to MPEG-1 conversion with libavcodec for use with - DVB/DXR3/IVTV/V4L2. - - - :1-31: fixed qscale - :32-: fixed bitrate in kbits - - - force output fps (float value) (default: 0, autodetect based on height) - -dvbscale[=aspect] - Set up optimal scaling for DVB cards, scaling the x axis in hardware and - calculating the y axis scaling in software to keep aspect. Only useful - together with expand and scale. - - - Control aspect ratio, calculate as ``DVB_HEIGHT*ASPECTRATIO`` (default: - ``576*4/3=768``), set it to ``576*(16/9)=1024`` for a 16:9 TV. - - *EXAMPLE*: - - ``--vf=dvbscale,scale=-1:0,expand=-1:576:-1:-1:1,lavc`` - FIXME: Explain what this does. - noise[=luma[u][t|a][h][p]:chroma[u][t|a][h][p]] Adds noise. @@ -528,7 +391,7 @@ noise[=luma[u][t|a][h][p]:chroma[u][t|a][h][p]] :h: high quality (slightly better looking, slightly slower) :p: mix random noise with a (semi)regular pattern -denoise3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp] +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.). @@ -542,36 +405,10 @@ denoise3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp] chroma temporal strength (default: ``luma_tmp*chroma_spatial/luma_spatial``) -hqdn3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp] - High precision/quality version of the denoise3d filter. Parameters and - usage are the same. - -ow[=depth[:luma_strength[:chroma_strength]]] - Overcomplete Wavelet denoiser. - - - Larger depth values will denoise lower frequency components more, but - slow down filtering (default: 8). - - luma strength (default: 1.0) - - chroma strength (default: 1.0) - -eq[=brightness:contrast] (OBSOLETE) - Software equalizer with interactive controls just like the hardware - equalizer, for cards/drivers that do not support brightness and contrast - controls in hardware. - - <-100-100> - initial brightness - <-100-100> - initial contrast - eq2[=gamma:contrast:brightness:saturation:rg:gg:bg:weight] - Alternative software equalizer that uses lookup tables (very slow), + Software equalizer that uses lookup tables (slow), allowing gamma correction in addition to simple brightness and contrast - adjustment. Note that it uses the same MMX optimized code as ``--vf=eq`` - if all gamma values are 1.0. The parameters are given as floating point + adjustment. The parameters are given as floating point values. <0.1-10> @@ -595,31 +432,6 @@ eq2[=gamma:contrast:brightness:saturation:rg:gg:bg:weight] 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). -hue[=hue:saturation] - Software equalizer with interactive controls just like the hardware - equalizer, for cards/drivers that do not support hue and saturation - controls in hardware. - - <-180-180> - initial hue (default: 0.0) - <-100-100> - initial saturation, where negative values result in a negative chroma - (default: 1.0) - -halfpack[=f] - Convert planar YUV 4:2:0 to half-height packed 4:2:2, downsampling luma - but keeping all chroma samples. Useful for output to low-resolution - display devices when hardware downscaling is poor quality or is not - available. Can also be used as a primitive luma-only deinterlacer with - very low CPU usage. - - - By default, halfpack averages pairs of lines when downsampling. Any - value different from 0 or 1 gives the default (averaging) behavior. - - :0: Only use even lines when downsampling. - :1: Only use odd lines when downsampling. - 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 @@ -633,60 +445,6 @@ ilpack[=mode] :0: nearest-neighbor sampling, fast but incorrect :1: linear interpolation (default) -decimate[=max:hi:lo:frac] - Drops frames that do not differ greatly from the previous frame in order - to reduce framerate. The main use of this filter is for very-low- bitrate - encoding (e.g. streaming over dialup modem), but it could in theory be - used for fixing movies that were inverse-telecined incorrectly. - - - Sets the maximum number of consecutive frames which can be dropped (if - positive), or the minimum interval between dropped frames (if - negative). - ,, - A frame is a candidate for dropping if no 8x8 region differs by more - than a threshold of , and if not more than portion (1 - meaning the whole image) differs by more than a threshold of . - Values of and are for 8x8 pixel blocks and represent actual - pixel value differences, so a threshold of 64 corresponds to 1 unit of - difference for each pixel, or the same spread out differently over the - block. - -dint[=sense:level] - The drop-deinterlace (dint) filter detects and drops the first from a set - of interlaced video frames. - - <0.0-1.0> - relative difference between neighboring pixels (default: 0.1) - <0.0-1.0> - What part of the image has to be detected as interlaced to drop the - frame (default: 0.15). - -lavcdeint (OBSOLETE) - FFmpeg deinterlacing filter, same as ``--vf=pp=fd`` - -kerndeint[=thresh[:map[:order[:sharp[:twoway]]]]] - Donald Graft's adaptive kernel deinterlacer. Deinterlaces parts of a video - if a configurable threshold is exceeded. - - <0-255> - threshold (default: 10) - - :0: Ignore pixels exceeding the threshold (default). - :1: Paint pixels exceeding the threshold white. - - - :0: Leave fields alone (default). - :1: Swap fields. - - - :0: Disable additional sharpening (default). - :1: Enable additional sharpening. - - - :0: Disable twoway sharpening (default). - :1: Enable twoway sharpening. - unsharp[=l|cWxH:amount[:l|cWxH:amount]] unsharp mask / gaussian blur @@ -710,81 +468,6 @@ unsharp[=l|cWxH:amount[:l|cWxH:amount]] swapuv Swap U & V plane. -il[=d|i][s][:[d|i][s]] - (De)interleaves lines. The goal of this filter is to add the ability to - process interlaced images pre-field without deinterlacing them. You can - filter your interlaced DVD and play it on a TV without breaking the - interlacing. While deinterlacing (with the postprocessing filter) removes - interlacing permanently (by smoothing, averaging, etc) deinterleaving - splits the frame into 2 fields (so called half pictures), so you can - process (filter) them independently and then re-interleave them. - - :d: deinterleave (placing one above the other) - :i: interleave - :s: swap fields (exchange even & odd lines) - -fil[=i|d] - (De)interleaves lines. This filter is very similar to the il filter but - much faster, the main disadvantage is that it does not always work. - Especially if combined with other filters it may produce randomly messed - up images, so be happy if it works but do not complain if it does not for - your combination of filters. - - :d: Deinterleave fields, placing them side by side. - :i: Interleave fields again (reversing the effect of fil=d). - -field[=n] - Extracts a single field from an interlaced image using stride arithmetic - to avoid wasting CPU time. The optional argument n specifies whether to - extract the even or the odd field (depending on whether n is even or odd). - -detc[=var1=value1:var2=value2:...] - Attempts to reverse the 'telecine' process to recover a clean, - non-interlaced stream at film framerate. This was the first and most - primitive inverse telecine filter to be added to MPlayer. It works by - latching onto the telecine 3:2 pattern and following it as long as - possible. This makes it suitable for perfectly-telecined material, even in - the presence of a fair degree of noise, but it will fail in the presence - of complex post-telecine edits. Development on this filter is no longer - taking place, as ivtc, pullup, and filmdint are better for most - applications. The following arguments (see syntax above) may be used to - control detc's behavior: - - - Set the frame dropping mode. - - :0: Do not drop frames to maintain fixed output framerate (default). - :1: Always drop a frame when there have been no drops or telecine - merges in the past 5 frames. - :2: Always maintain exact 5:4 input to output frame ratio. - - - Analysis mode. - - :0: Fixed pattern with initial frame number specified by . - :1: aggressive search for telecine pattern (default) - - - Set initial frame number in sequence. 0-2 are the three clean - progressive frames; 3 and 4 are the two interlaced frames. The - default, -1, means 'not in telecine sequence'. The number specified - here is the type for the imaginary previous frame before the movie - starts. - - , , , - Threshold values to be used in certain modes. - -ivtc[=1] - Experimental 'stateless' inverse telecine filter. Rather than trying to - lock on to a pattern like the detc filter does, ivtc makes its decisions - independently for each frame. This will give much better results for - material that has undergone heavy editing after telecine was applied, but - as a result it is not as forgiving of noisy input, for example TV capture. - The optional parameter (ivtc=1) corresponds to the dr=1 option for the - detc filter, and should not be used with MPlayer. Further development on - ivtc has stopped, as the pullup and filmdint filters appear to be much - more accurate. - pullup[=jl:jr:jt:jb:sb:mp] Third-generation pulldown reversal (inverse telecine) filter, capable of handling mixed hard-telecine, 24000/1001 fps progressive, and 30000/1001 @@ -818,75 +501,6 @@ pullup[=jl:jr:jt:jb:sb:mp] 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. -filmdint[=options] - Inverse telecine filter, similar to the pullup filter above. It is - designed to handle any pulldown pattern, including mixed soft and hard - telecine and limited support for movies that are slowed down or sped up - from their original framerate for TV. Only the luma plane is used to find - the frame breaks. If a field has no match, it is deinterlaced with simple - linear approximation. If the source is MPEG-2, this must be the first - filter to allow access to the field-flags set by the MPEG-2 decoder. - Depending on the source MPEG, you may be fine ignoring this advice, as - long as you do not see lots of "Bottom-first field" warnings. With no - options it does normal inverse telecine. When this filter is used with - MPlayer, it will result in an uneven framerate during playback, but it is - still generally better than using pp=lb or no deinterlacing at all. - Multiple options can be specified separated by /. - - crop=::: - Just like the crop filter, but faster, and works on mixed hard and - soft telecined content as well as when y is not a multiple of 4. If x - or y would require cropping fractional pixels from the chroma planes, - the crop area is extended. This usually means that x and y must be - even. - - io=: - For each ifps input frames the filter will output ofps frames. This - could be used to filter movies that are broadcast on TV at a frame - rate different from their original framerate. - - luma_only= - If n is nonzero, the chroma plane is copied unchanged. This is useful - for YV12 sampled TV, which discards one of the chroma fields. - - mmx2= - On x86, if n=1, use MMX2 optimized functions, if n=2, use 3DNow! - optimized functions, otherwise, use plain C. If this option is not - specified, MMX2 and 3DNow! are auto-detected, use this option to - override auto-detection. - - fast= - The larger n will speed up the filter at the expense of accuracy. The - default value is n=3. If n is odd, a frame immediately following a - frame marked with the REPEAT_FIRST_FIELD MPEG flag is assumed to be - progressive, thus filter will not spend any time on soft-telecined - MPEG-2 content. This is the only effect of this flag if MMX2 or 3DNow! - is available. Without MMX2 and 3DNow, if n=0 or 1, the same - calculations will be used as with n=2 or 3. If n=2 or 3, the number of - luma levels used to find the frame breaks is reduced from 256 to 128, - which results in a faster filter without losing much accuracy. If n=4 - or 5, a faster, but much less accurate metric will be used to find the - frame breaks, which is more likely to misdetect high vertical detail - as interlaced content. - - verbose= - If n is nonzero, print the detailed metrics for each frame. Useful for - debugging. - - dint_thres= - Deinterlace threshold. Used during de-interlacing of unmatched frames. - Larger value means less deinterlacing, use n=256 to completely turn - off deinterlacing. Default is n=8. - - comb_thres= - Threshold for comparing a top and bottom fields. Defaults to 128. - - diff_thres= - Threshold to detect temporal change of a field. Default is 128. - - sad_thres= - Sum of Absolute Difference threshold, default is 64. - 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 @@ -1002,49 +616,6 @@ phase[=t|b|p|a|u|T|B|A|U][:v] average squared difference between fields for t, b, and p alternatives. -telecine[=start] - Apply 3:2 'telecine' process to increase framerate by 20%. This most - likely will not work correctly with MPlayer. The optional start parameter - tells the filter where in the telecine pattern to start (0-3). - -tinterlace[=mode] - Temporal field interlacing - merge pairs of frames into an interlaced - frame, halving the framerate. Even frames are moved into the upper field, - odd frames to the lower field. This can be used to fully reverse the - effect of the tfields filter (in mode 0). Available modes are: - - :0: Move odd frames into the upper field, even into the lower field, - generating a full-height frame at half framerate. - :1: Only output odd frames, even frames are dropped; height unchanged. - :2: Only output even frames, odd frames are dropped; height unchanged. - :3: Expand each frame to full height, but pad alternate lines with black; - framerate unchanged. - :4: Interleave even lines from even frames with odd lines from odd frames. - Height unchanged at half framerate. - -tfields[=mode[:field_dominance]] - Temporal field separation - split fields into frames, doubling the output - framerate. - - - :0: Leave fields unchanged (will jump/flicker). - :1: Interpolate missing lines. (The algorithm used might not be so - good.) - :2: Translate fields by 1/4 pixel with linear interpolation (no jump). - :4: Translate fields by 1/4 pixel with 4tap filter (higher quality) - (default). - - (DEPRECATED) - :-1: auto (default) Only works if the decoder exports the appropriate - information and no other filters which discard that information - come before tfields in the filter chain, otherwise it falls back - to 0 (top field first). - :0: top field first - :1: bottom field first - - *NOTE*: This option will possibly be removed in a future version. Use - ``--field-dominance`` instead. - yadif=[mode[:field_dominance]] Yet another deinterlacing filter @@ -1060,66 +631,6 @@ yadif=[mode[:field_dominance]] *NOTE*: This option will possibly be removed in a future version. Use ``--field-dominance`` instead. -mcdeint=[mode[:parity[:qp]]] - Motion compensating deinterlacer. It needs one field per frame as input - and must thus be used together with tfields=1 or yadif=1/3 or equivalent. - - - :0: fast - :1: medium - :2: slow, iterative motion estimation - :3: extra slow, like 2 plus multiple reference frames - - - 0 or 1 selects which field to use (note: no autodetection yet!). - - - Higher values should result in a smoother motion vector field but less - optimal individual vectors. - -boxblur=radius:power[:radius:power] - box blur - - - blur filter strength - - number of filter applications - -sab=radius:pf:colorDiff[:radius:pf:colorDiff] - shape adaptive blur - - - blur filter strength (~0.1-4.0) (slower if larger) - - prefilter strength (~0.1-2.0) - - maximum difference between pixels to still be considered (~0.1-100.0) - -smartblur=radius:strength:threshold[:radius:strength:threshold] - smart blur - - - blur filter strength (~0.1-5.0) (slower if larger) - - blur (0.0-1.0) or sharpen (-1.0-0.0) - - filter all (0), filter flat areas (0-30) or filter edges (-30-0) - -perspective=x0:y0:x1:y1:x2:y2:x3:y3:t - Correct the perspective of movies not filmed perpendicular to the screen. - - ,,... - coordinates of the top left, top right, bottom left, bottom right - corners - - linear (0) or cubic resampling (1) - -2xsai - Scale and smooth the image with the 2x scale and interpolate algorithm. - -1bpp - 1bpp bitmap to YUV/BGR 8/15/16/32 conversion - down3dright[=lines] Reposition and resize stereoscopic images. Extracts both stereo fields and places them side by side, resizing them to maintain the original movie @@ -1128,108 +639,6 @@ down3dright[=lines] number of lines to select from the middle of the image (default: 12) -bmovl=hidden:opaque:fifo - The bitmap overlay filter reads bitmaps from a FIFO and displays them on - top of the movie, allowing some transformations on the image. See also - ``TOOLS/bmovl-test.c`` for a small bmovl test program. - - - Set the default value of the 'hidden' flag (0=visible, 1=hidden). - - Set the default value of the 'opaque' flag (0=transparent, 1=opaque). - - path/filename for the FIFO (named pipe connecting ``mplayer - --vf=bmovl`` to the controlling application) - - FIFO commands are: - - RGBA32 width height xpos ypos alpha clear - followed by width*height*4 Bytes of raw RGBA32 data. - ABGR32 width height xpos ypos alpha clear - followed by width*height*4 Bytes of raw ABGR32 data. - RGB24 width height xpos ypos alpha clear - followed by width*height*3 Bytes of raw RGB24 data. - BGR24 width height xpos ypos alpha clear - followed by width*height*3 Bytes of raw BGR24 data. - ALPHA width height xpos ypos alpha - Change alpha transparency of the specified area. - CLEAR width height xpos ypos - Clear area. - OPAQUE - Disable all alpha transparency. Send "ALPHA 0 0 0 0 0" to enable it - again. - HIDE - Hide bitmap. - SHOW - Show bitmap. - - Arguments are: - - , - image/area size - , - Start blitting at position x/y. - - Set alpha difference. If you set this to -255 you can then send a - sequence of ALPHA-commands to set the area to -225, -200, -175 etc for - a nice fade-in-effect! ;) - - :0: same as original - :255: Make everything opaque. - :-255: Make everything transparent. - - - Clear the framebuffer before blitting. - - :0: The image will just be blitted on top of the old one, so you do - not need to send 1.8MB of RGBA32 data every time a small part of - the screen is updated. - :1: clear - -framestep=I|[i]step - Renders only every nth frame or every intra frame (keyframe). - - If you call the filter with I (uppercase) as the parameter, then *only* - keyframes are rendered. For DVDs it generally means one in every 15/12 - frames (IBBPBBPBBPBBPBB), for AVI it means every scene change or every - keyint value. - - When a keyframe is found, an 'I!' string followed by a newline character - is printed, leaving the current line of MPlayer output on the screen, - because it contains the time (in seconds) and frame number of the keyframe - (You can use this information to split the AVI.). - - If you call the filter with a numeric parameter 'step' then only one in - every 'step' frames is rendered. - - If you put an 'i' (lowercase) before the number then an 'I!' is printed - (like the I parameter). - - If you give only the i then nothing is done to the frames, only I! is - printed. - -tile=xtiles:ytiles:output:start:delta - Tile a series of images into a single, bigger image. If you omit a - parameter or use a value less than 0, then the default value is used. You - can also stop when you are satisfied (``... --vf=tile=10:5 ...``). It is - probably a good idea to put the scale filter before the tile :-) - - The parameters are: - - - number of tiles on the x axis (default: 5) - - number of tiles on the y axis (default: 5) - - Render the tile when 'output' number of frames are reached, where - 'output' should be a number less than xtile * ytile. Missing tiles are - left blank. You could, for example, write an 8 * 7 tile every 50 - frames to have one image every 2 seconds @ 25 fps. - - outer border thickness in pixels (default: 2) - - inner border thickness in pixels (default: 4) - delogo[=x:y:w:h:t] Suppresses a TV station logo by a simple interpolation of the surrounding pixels. Just set a rectangle covering the logo and watch it disappear (and @@ -1248,15 +657,6 @@ delogo[=x:y:w:h:t] must have a timestamp (in seconds, and in ascending order) and the "x:y:w:h:t" coordinates (*t* can be omitted). -remove-logo=/path/to/logo_bitmap_file_name.pgm - Suppresses a TV station logo, using a PGM or PPM image file to determine - which pixels comprise the logo. The width and height of the image file - must match those of the video stream being processed. Uses the filter - image and a circular blur algorithm to remove the logo. - - ``/path/to/logo_bitmap_file_name.pgm`` - [path] + filename of the filter image. - screenshot Optional filter for screenshot support. This is only needed if the video output doesn't provide working direct screenshot support. Note that it is @@ -1275,19 +675,6 @@ ass subtitle colors and video under the influence of the video equalizer settings. -blackframe[=amount:threshold] - Detect frames that are (almost) completely black. Can be useful to detect - chapter transitions or commercials. Output lines consist of the frame - number of the detected frame, the percentage of blackness, the frame type - and the frame number of the last encountered keyframe. - - - Percentage of the pixels that have to be below the threshold (default: - 98). - - - Threshold below which a pixel value is considered black (default: 32). - stereo3d[=in:out] Stereo3d converts between different stereoscopic image formats. @@ -1373,39 +760,6 @@ gradfun[=strength[:radius]] gradients, but also prevents the filter from modifying pixels near detailed regions (default: 16). -fixpts[=options] - Fixes the presentation timestamps (PTS) of the frames. By default, the PTS - passed to the next filter is dropped, but the following options can change - that: - - print - Print the incoming PTS. - - fps= - Specify a frame per second value. - - start= - Specify an initial value for the PTS. - - autostart= - Uses the *n*\th incoming PTS as the initial PTS. All previous PTS are - kept, so setting a huge value or -1 keeps the PTS intact. - - autofps= - Uses the *n*\th incoming PTS after the end of autostart to determine - the framerate. - - *EXAMPLE*: - - ``--vf=fixpts=fps=24000/1001,ass,fixpts`` - Generates a new sequence of PTS, uses it for ASS subtitles, then drops - it. Generating a new sequence is useful when the timestamps are reset - during the program; this is frequent on DVDs. Dropping it may be - necessary to avoid confusing encoders. - - *NOTE*: Using this filter together with any sort of seeking (including - ``--ss``) may make demons fly out of your nose. - dlopen=dll[:a0[:a1[:a2[:a3]]]] Loads an external library to filter the image. The library interface is the vf_dlopen interface specified using libmpcodecs/vf_dlopen.h. diff --git a/Makefile b/Makefile index c93fa6b31c..41f265b436 100644 --- a/Makefile +++ b/Makefile @@ -34,13 +34,8 @@ SRCS_COMMON-$(DVBIN) += stream/dvb_tune.c \ SRCS_COMMON-$(DVDREAD) += stream/stream_dvd.c \ stream/stream_dvd_common.c -# These filters use private headers and do not work with shared libavcodec. -SRCS_COMMON-$(FFMPEG_INTERNALS) += libmpcodecs/vf_mcdeint.c \ - libmpcodecs/vf_spp.c \ - SRCS_COMMON-$(FTP) += stream/stream_ftp.c SRCS_COMMON-$(GIF) += libmpdemux/demux_gif.c -SRCS_COMMON-$(HAVE_POSIX_SELECT) += libmpcodecs/vf_bmovl.c SRCS_COMMON-$(HAVE_SYS_MMAN_H) += libaf/af_export.c osdep/mmap_anon.c SRCS_COMMON-$(LADSPA) += libaf/af_ladspa.c SRCS_COMMON-$(LIBASS) += libmpcodecs/vf_ass.c \ @@ -152,77 +147,33 @@ SRCS_COMMON = asxparser.c \ libmpcodecs/vd.c \ libmpcodecs/vd_ffmpeg.c \ libmpcodecs/vf.c \ - libmpcodecs/vf_1bpp.c \ - libmpcodecs/vf_2xsai.c \ - libmpcodecs/vf_blackframe.c \ - libmpcodecs/vf_boxblur.c \ libmpcodecs/vf_crop.c \ - libmpcodecs/vf_cropdetect.c \ - libmpcodecs/vf_decimate.c \ libmpcodecs/vf_delogo.c \ - libmpcodecs/vf_denoise3d.c \ - libmpcodecs/vf_detc.c \ - libmpcodecs/vf_dint.c \ libmpcodecs/vf_divtc.c \ libmpcodecs/vf_dlopen.c \ libmpcodecs/vf_down3dright.c \ libmpcodecs/vf_dsize.c \ - libmpcodecs/vf_dvbscale.c \ - libmpcodecs/vf_eq.c \ libmpcodecs/vf_eq2.c \ libmpcodecs/vf_expand.c \ - libmpcodecs/vf_field.c \ - libmpcodecs/vf_fil.c \ - libmpcodecs/vf_filmdint.c \ - libmpcodecs/vf_fixpts.c \ libmpcodecs/vf_flip.c \ libmpcodecs/vf_format.c \ - libmpcodecs/vf_framestep.c \ - libmpcodecs/vf_fspp.c \ - libmpcodecs/vf_geq.c \ libmpcodecs/vf_gradfun.c \ - libmpcodecs/vf_halfpack.c \ - libmpcodecs/vf_harddup.c \ libmpcodecs/vf_hqdn3d.c \ - libmpcodecs/vf_hue.c \ - libmpcodecs/vf_il.c \ libmpcodecs/vf_ilpack.c \ - libmpcodecs/vf_ivtc.c \ - libmpcodecs/vf_kerndeint.c \ - libmpcodecs/vf_lavc.c \ - libmpcodecs/vf_lavcdeint.c \ libmpcodecs/vf_mirror.c \ libmpcodecs/vf_noformat.c \ libmpcodecs/vf_noise.c \ - libmpcodecs/vf_ow.c \ - libmpcodecs/vf_palette.c \ - libmpcodecs/vf_perspective.c \ libmpcodecs/vf_phase.c \ - libmpcodecs/vf_pp7.c \ libmpcodecs/vf_pullup.c \ - libmpcodecs/vf_qp.c \ - libmpcodecs/vf_remove_logo.c \ - libmpcodecs/vf_rgbtest.c \ libmpcodecs/vf_rotate.c \ - libmpcodecs/vf_sab.c \ libmpcodecs/vf_scale.c \ libmpcodecs/vf_screenshot.c \ - libmpcodecs/vf_smartblur.c \ libmpcodecs/vf_softpulldown.c \ libmpcodecs/vf_stereo3d.c \ - libmpcodecs/vf_softskip.c \ libmpcodecs/vf_swapuv.c \ - libmpcodecs/vf_telecine.c \ - libmpcodecs/vf_test.c \ - libmpcodecs/vf_tfields.c \ - libmpcodecs/vf_tile.c \ - libmpcodecs/vf_tinterlace.c \ libmpcodecs/vf_unsharp.c \ - libmpcodecs/vf_uspp.c \ libmpcodecs/vf_vo.c \ libmpcodecs/vf_yadif.c \ - libmpcodecs/vf_yuvcsp.c \ - libmpcodecs/vf_yvu9.c \ libmpdemux/asfheader.c \ libmpdemux/aviheader.c \ libmpdemux/aviprint.c \ @@ -456,9 +407,6 @@ checkheaders: $(ALLHEADERS:.h=.ho) version.c osdep/mplayer-rc.o: version.h -# Files that depend on libavcodec internals -libmpcodecs/vf_fspp.o libmpcodecs/vf_mcdeint.o libmpcodecs/vf_spp.o: CFLAGS := -I$(FFMPEG_SOURCE_PATH) $(CFLAGS) - osdep/mplayer-rc.o: osdep/mplayer.exe.manifest diff --git a/configure b/configure index cdcbdbcad2..7e02acc877 100755 --- a/configure +++ b/configure @@ -435,7 +435,6 @@ _opt=-O2 _cross_compile=no _prefix="/usr/local" ffmpeg=auto -ffmpeg_internals=no _mplayer=yes _encoding=yes _x11=auto @@ -715,8 +714,6 @@ for ac_option do --enable-joystick) _joystick=yes ;; --disable-joystick) _joystick=no ;; --enable-libav) ffmpeg=yes ;; - --ffmpeg-source-dir=*) - _ffmpeg_source=$(echo $ac_option | cut -d '=' -f 2 ) ;; --enable-lirc) _lirc=yes ;; --disable-lirc) _lirc=no ;; @@ -2933,10 +2930,6 @@ if test "$ffmpeg" = auto ; then fi echores "yes" -def_ffmpeg_internals="#undef CONFIG_FFMPEG_INTERNALS" -if ! test -z "$_ffmpeg_source" ; then - def_ffmpeg_internals="#define CONFIG_FFMPEG_INTERNALS 1" && ffmpeg_internals=yes -fi echocheck "libpostproc >= 52.0.0" if test "$libpostproc" = auto ; then @@ -3399,8 +3392,6 @@ XV = $_xv # FFmpeg ENCODING = $_encoding -FFMPEG_INTERNALS = $ffmpeg_internals -FFMPEG_SOURCE_PATH = $_ffmpeg_source CONFIG_VDPAU = $_vdpau CONFIG_ZLIB = $_zlib @@ -3617,7 +3608,6 @@ $def_xv /* FFmpeg */ $def_encoding -$def_ffmpeg_internals $def_fast_64bit $def_mkstemp diff --git a/libmpcodecs/cmmx.h b/libmpcodecs/cmmx.h deleted file mode 100644 index 51ffd235bc..0000000000 --- a/libmpcodecs/cmmx.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * x86 MMX and MMX2 packed byte operations in portable C. - * Extra instructions: pdiffub, pcmpzb, psumbw, pcmpgtub - * Author: Zoltan Hidvegi - * - * This file is part of MPlayer. - * - * 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. - */ - -#ifndef MPLAYER_CMMX_H -#define MPLAYER_CMMX_H - -typedef unsigned long cmmx_t; - -#define ONE_BYTES (~(cmmx_t)0 / 255) -#define SIGN_BITS (ONE_BYTES << 7) -#define LOWBW_MASK (~(cmmx_t)0 / 257) - -static inline cmmx_t -paddb(cmmx_t a, cmmx_t b) -{ - return ((a & ~SIGN_BITS) + (b & ~SIGN_BITS)) ^ ((a^b) & SIGN_BITS); -} - -static inline cmmx_t -psubb(cmmx_t a, cmmx_t b) -{ - return ((a | SIGN_BITS) - (b & ~SIGN_BITS)) ^ (~(a^b) & SIGN_BITS); -} - -static inline cmmx_t -paddusb(cmmx_t a, cmmx_t b) -{ - cmmx_t s = (a & ~SIGN_BITS) + (b & ~SIGN_BITS); - cmmx_t abs = (a | b) & SIGN_BITS; - cmmx_t c = abs & (s | (a & b)); - return s | abs | (abs - (c >> 7)); -} - -static inline cmmx_t -paddusb_s(cmmx_t a, cmmx_t b) -{ - cmmx_t sum = a+b; - cmmx_t ov = sum & SIGN_BITS; - return sum + (sum ^ (ov - (ov>>7))); -} - -static inline cmmx_t -psubusb(cmmx_t a, cmmx_t b) -{ - cmmx_t s = (a | SIGN_BITS) - (b & ~SIGN_BITS); - cmmx_t anb = a & ~b; - cmmx_t c = (anb | (s & ~(a^b))) & SIGN_BITS; - return s & ((c & anb) | (c - (c >> 7))); -} - -static inline cmmx_t -psubusb_s(cmmx_t a, cmmx_t b) -{ - cmmx_t d = (a|SIGN_BITS) - b; - cmmx_t m = d & SIGN_BITS; - return d & (m - (m>>7)); -} - -static inline cmmx_t -pcmpgtub(cmmx_t b, cmmx_t a) -{ - cmmx_t s = (a | SIGN_BITS) - (b & ~SIGN_BITS); - cmmx_t ret = ((~a & b) | (~s & ~(a ^ b))) & SIGN_BITS; - return ret | (ret - (ret >> 7)); -} - -static inline cmmx_t -pdiffub(cmmx_t a, cmmx_t b) -{ - cmmx_t xs = (~a ^ b) & SIGN_BITS; - cmmx_t s = ((a | SIGN_BITS) - (b & ~SIGN_BITS)) ^ xs; - cmmx_t gt = ((~a & b) | (s & xs)) & SIGN_BITS; - cmmx_t gt7 = gt >> 7; - return (s ^ gt ^ (gt - gt7)) + gt7; -} - -static inline cmmx_t -pdiffub_s(cmmx_t a, cmmx_t b) -{ - cmmx_t d = (a|SIGN_BITS) - b; - cmmx_t g = (~d & SIGN_BITS) >> 7; - return (d ^ (SIGN_BITS-g)) + g; -} - -static inline cmmx_t -pmaxub(cmmx_t a, cmmx_t b) -{ - return psubusb(a,b) + b; -} - -static inline cmmx_t -pminub(cmmx_t a, cmmx_t b) -{ - return paddusb(a,~b) - ~b; -} - -static inline cmmx_t -pminub_s(cmmx_t a, cmmx_t b) -{ - cmmx_t d = (a|SIGN_BITS) - b; - cmmx_t m = ~SIGN_BITS + ((d&SIGN_BITS)>>7); - return ((d&m) + b) & ~SIGN_BITS; -} - -static inline cmmx_t -pavgb(cmmx_t a, cmmx_t b) -{ - cmmx_t ao = a & ONE_BYTES; - cmmx_t bo = b & ONE_BYTES; - return ((a^ao)>>1) + ((b^bo)>>1) + (ao|bo); -} - -static inline cmmx_t -pavgb_s(cmmx_t a, cmmx_t b) -{ - return ((a+b+ONE_BYTES)>>1) & ~SIGN_BITS; -} - -static inline cmmx_t -p31avgb(cmmx_t a, cmmx_t b) -{ - cmmx_t ao = a & (3*ONE_BYTES); - cmmx_t bo = b & (3*ONE_BYTES); - return 3*((a^ao)>>2) + ((b^bo)>>2) + - (((3*ao+bo+2*ONE_BYTES)>>2) & (3*ONE_BYTES)); -} - -static inline cmmx_t -p31avgb_s(cmmx_t a, cmmx_t b) -{ - cmmx_t avg = ((a+b)>>1) & ~SIGN_BITS; - return pavgb_s(avg, a); -} - -static inline unsigned long -psumbw(cmmx_t a) -{ - cmmx_t t = (a & LOWBW_MASK) + ((a>>8) & LOWBW_MASK); - unsigned long ret = - (unsigned long)t + (unsigned long)(t >> (4*sizeof(cmmx_t))); - if (sizeof(cmmx_t) > 4) - ret += ret >> 16; - return ret & 0xffff; -} - -static inline unsigned long -psumbw_s(cmmx_t a) -{ - unsigned long ret = - (unsigned long)a + (unsigned long)(a >> (4*sizeof(cmmx_t))); - if (sizeof(cmmx_t) <= 4) - return (ret & 0xff) + ((ret>>8) & 0xff); - ret = (ret & 0xff00ff) + ((ret>>8) & 0xff00ff); - ret += ret >> 16; - return ret & 0xffff; -} - -static inline unsigned long -psadbw(cmmx_t a, cmmx_t b) -{ - return psumbw(pdiffub(a,b)); -} - -static inline unsigned long -psadbw_s(cmmx_t a, cmmx_t b) -{ - return psumbw_s(pdiffub_s(a,b)); -} - -static inline cmmx_t -pcmpzb(cmmx_t a) -{ - cmmx_t ret = (((a | SIGN_BITS) - ONE_BYTES) | a) & SIGN_BITS; - return ~(ret | (ret - (ret >> 7))); -} - -static inline cmmx_t -pcmpeqb(cmmx_t a, cmmx_t b) -{ - return pcmpzb(a ^ b); -} - -#endif /* MPLAYER_CMMX_H */ diff --git a/libmpcodecs/vd_null.c b/libmpcodecs/vd_null.c deleted file mode 100644 index 894585b42f..0000000000 --- a/libmpcodecs/vd_null.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include - -#include "config.h" -#include "mp_msg.h" - -#include "vd_internal.h" - -static const vd_info_t info = -{ - "Null video decoder", - "null", - "A'rpi", - "A'rpi", - "no decoding" -}; - -LIBVD_EXTERN(null) - -// to set/get/query special features/parameters -static int control(sh_video_t *sh,int cmd,void* arg,...){ - return CONTROL_UNKNOWN; -} - -// init driver -static int init(sh_video_t *sh){ - if(!mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_BGR24)) return 0; - return 1; -} - -// uninit driver -static void uninit(sh_video_t *sh){ -} - -// decode a frame -static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){ - return NULL; -} diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c index f847dd69b8..5ec7d19570 100644 --- a/libmpcodecs/vf.c +++ b/libmpcodecs/vf.c @@ -38,7 +38,6 @@ #include "libvo/fastmemcpy.h" extern const vf_info_t vf_info_vo; -extern const vf_info_t vf_info_bmovl; extern const vf_info_t vf_info_crop; extern const vf_info_t vf_info_expand; extern const vf_info_t vf_info_pp; @@ -48,161 +47,65 @@ extern const vf_info_t vf_info_noformat; extern const vf_info_t vf_info_flip; extern const vf_info_t vf_info_rotate; extern const vf_info_t vf_info_mirror; -extern const vf_info_t vf_info_palette; -extern const vf_info_t vf_info_lavc; -extern const vf_info_t vf_info_dvbscale; -extern const vf_info_t vf_info_cropdetect; -extern const vf_info_t vf_info_test; extern const vf_info_t vf_info_noise; -extern const vf_info_t vf_info_yvu9; -extern const vf_info_t vf_info_lavcdeint; -extern const vf_info_t vf_info_eq; extern const vf_info_t vf_info_eq2; extern const vf_info_t vf_info_gradfun; -extern const vf_info_t vf_info_halfpack; -extern const vf_info_t vf_info_dint; -extern const vf_info_t vf_info_1bpp; -extern const vf_info_t vf_info_2xsai; extern const vf_info_t vf_info_unsharp; extern const vf_info_t vf_info_swapuv; -extern const vf_info_t vf_info_il; -extern const vf_info_t vf_info_fil; -extern const vf_info_t vf_info_boxblur; -extern const vf_info_t vf_info_sab; -extern const vf_info_t vf_info_smartblur; -extern const vf_info_t vf_info_perspective; extern const vf_info_t vf_info_down3dright; -extern const vf_info_t vf_info_field; -extern const vf_info_t vf_info_denoise3d; extern const vf_info_t vf_info_hqdn3d; -extern const vf_info_t vf_info_detc; -extern const vf_info_t vf_info_telecine; -extern const vf_info_t vf_info_tinterlace; -extern const vf_info_t vf_info_tfields; -extern const vf_info_t vf_info_ivtc; extern const vf_info_t vf_info_ilpack; extern const vf_info_t vf_info_dsize; -extern const vf_info_t vf_info_decimate; extern const vf_info_t vf_info_softpulldown; extern const vf_info_t vf_info_pullup; -extern const vf_info_t vf_info_filmdint; -extern const vf_info_t vf_info_framestep; -extern const vf_info_t vf_info_tile; extern const vf_info_t vf_info_delogo; -extern const vf_info_t vf_info_remove_logo; -extern const vf_info_t vf_info_hue; -extern const vf_info_t vf_info_spp; -extern const vf_info_t vf_info_uspp; -extern const vf_info_t vf_info_fspp; -extern const vf_info_t vf_info_pp7; -extern const vf_info_t vf_info_yuvcsp; -extern const vf_info_t vf_info_kerndeint; -extern const vf_info_t vf_info_rgbtest; -extern const vf_info_t vf_info_qp; extern const vf_info_t vf_info_phase; extern const vf_info_t vf_info_divtc; -extern const vf_info_t vf_info_harddup; extern const vf_info_t vf_info_softskip; extern const vf_info_t vf_info_screenshot; extern const vf_info_t vf_info_screenshot_force; extern const vf_info_t vf_info_ass; -extern const vf_info_t vf_info_mcdeint; extern const vf_info_t vf_info_yadif; -extern const vf_info_t vf_info_blackframe; -extern const vf_info_t vf_info_geq; -extern const vf_info_t vf_info_ow; -extern const vf_info_t vf_info_fixpts; extern const vf_info_t vf_info_stereo3d; extern const vf_info_t vf_info_dlopen; // list of available filters: static const vf_info_t *const filter_list[] = { -#ifdef HAVE_POSIX_SELECT - &vf_info_bmovl, -#endif &vf_info_crop, &vf_info_expand, &vf_info_scale, -// &vf_info_osd, &vf_info_vo, &vf_info_format, &vf_info_noformat, &vf_info_flip, &vf_info_rotate, &vf_info_mirror, - &vf_info_palette, - &vf_info_pp7, #ifdef CONFIG_LIBPOSTPROC &vf_info_pp, #endif - &vf_info_lavc, - &vf_info_lavcdeint, + &vf_info_screenshot, &vf_info_screenshot_force, - &vf_info_fspp, - &vf_info_uspp, - &vf_info_dvbscale, - &vf_info_cropdetect, - &vf_info_test, &vf_info_noise, - &vf_info_yvu9, - &vf_info_eq, &vf_info_eq2, &vf_info_gradfun, - &vf_info_halfpack, - &vf_info_dint, - &vf_info_1bpp, - &vf_info_2xsai, &vf_info_unsharp, &vf_info_swapuv, - &vf_info_il, - &vf_info_fil, - &vf_info_boxblur, - &vf_info_sab, - &vf_info_smartblur, - &vf_info_perspective, &vf_info_down3dright, - &vf_info_field, - &vf_info_denoise3d, &vf_info_hqdn3d, - &vf_info_detc, - &vf_info_telecine, - &vf_info_tinterlace, - &vf_info_tfields, - &vf_info_ivtc, &vf_info_ilpack, &vf_info_dsize, - &vf_info_decimate, &vf_info_softpulldown, &vf_info_pullup, - &vf_info_filmdint, - &vf_info_framestep, - &vf_info_tile, &vf_info_delogo, - &vf_info_remove_logo, - &vf_info_hue, -#ifdef CONFIG_FFMPEG_INTERNALS - &vf_info_spp, - &vf_info_mcdeint, -#endif - &vf_info_geq, - &vf_info_qp, - &vf_info_yuvcsp, - &vf_info_kerndeint, - &vf_info_rgbtest, &vf_info_phase, &vf_info_divtc, - &vf_info_harddup, - &vf_info_softskip, #ifdef CONFIG_ASS &vf_info_ass, #endif &vf_info_yadif, - &vf_info_blackframe, - &vf_info_ow, - &vf_info_fixpts, &vf_info_stereo3d, &vf_info_dlopen, NULL diff --git a/libmpcodecs/vf_1bpp.c b/libmpcodecs/vf_1bpp.c deleted file mode 100644 index 8d13735942..0000000000 --- a/libmpcodecs/vf_1bpp.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -//===========================================================================// - -static const unsigned int bgr_list[]={ - IMGFMT_Y800, - IMGFMT_Y8, - IMGFMT_BGR8, - IMGFMT_RGB8, - - IMGFMT_YVU9, - IMGFMT_411P, - IMGFMT_YV12, - IMGFMT_I420, - IMGFMT_IYUV, - IMGFMT_422P, - IMGFMT_444P, - - IMGFMT_YUY2, - IMGFMT_BGR12, - IMGFMT_RGB12, - IMGFMT_BGR15, - IMGFMT_RGB15, - IMGFMT_BGR16, - IMGFMT_RGB16, - - IMGFMT_BGR32, - IMGFMT_RGB32, - -// IMGFMT_BGR24, -// IMGFMT_RGB24, - 0 -}; - -static unsigned int find_best(struct vf_instance *vf){ - unsigned int best=0; - int ret; - const unsigned int* p=bgr_list; - while(*p){ - ret=vf->next->query_format(vf->next,*p); - mp_msg(MSGT_VFILTER,MSGL_V,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3); - if(ret&VFCAP_CSP_SUPPORTED_BY_HW){ best=*p; break;} // no conversion -> bingo! - if(ret&VFCAP_CSP_SUPPORTED && !best) best=*p; // best with conversion - ++p; - } - return best; -} - -//===========================================================================// - -struct vf_priv_s { - unsigned int fmt; -}; - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - if (!vf->priv->fmt) - vf->priv->fmt=find_best(vf); - if(!vf->priv->fmt){ - // no matching fmt, so force one... - if(outfmt==IMGFMT_RGB8) vf->priv->fmt=IMGFMT_RGB32; - else if(outfmt==IMGFMT_BGR8) vf->priv->fmt=IMGFMT_BGR32; - else return 0; - } - return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt); -} - -static const int bittab[8]={128,64,32,16,8,4,2,1}; - -static void convert(mp_image_t *mpi, mp_image_t *dmpi, int value0, int value1,int bpp){ - int y; - for(y=0;yh;y++){ - unsigned char* src=mpi->planes[0]+mpi->stride[0]*y; - switch(bpp){ - case 1: { - unsigned char* dst=dmpi->planes[0]+dmpi->stride[0]*y; - int x; - for(x=0;xw;x++) - dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0; - break; } - case 2: { - uint16_t* dst=(uint16_t*)(dmpi->planes[0]+dmpi->stride[0]*y); - int x; - for(x=0;xw;x++) - dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0; - break; } - case 4: { - uint32_t* dst=(uint32_t*)(dmpi->planes[0]+dmpi->stride[0]*y); - int x; - for(x=0;xw;x++) - dst[x]=(src[x>>3]&bittab[x&7]) ? value1 : value0; - break; } - } - } -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - // hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,vf->priv->fmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w, mpi->h); - - switch(dmpi->imgfmt){ - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_BGR8: - case IMGFMT_RGB8: - convert(mpi,dmpi,0,255,1); - break; - case IMGFMT_YVU9: - case IMGFMT_411P: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_422P: - case IMGFMT_444P: - convert(mpi,dmpi,0,255,1); - memset(dmpi->planes[1],128,dmpi->stride[1]*dmpi->chroma_height); - memset(dmpi->planes[2],128,dmpi->stride[2]*dmpi->chroma_height); - break; - case IMGFMT_YUY2: - convert(mpi,dmpi,0x8000,0x80ff,2); - break; - case IMGFMT_BGR12: - case IMGFMT_RGB12: - convert(mpi,dmpi,0,0x0fff,2); - break; - case IMGFMT_BGR15: - case IMGFMT_RGB15: - convert(mpi,dmpi,0,0x7fff,2); - break; - case IMGFMT_BGR16: - case IMGFMT_RGB16: - convert(mpi,dmpi,0,0xffff,2); - break; - case IMGFMT_BGR32: - case IMGFMT_RGB32: - convert(mpi,dmpi,0,0x00ffffff,4); - break; - default: - mp_msg(MSGT_VFILTER,MSGL_ERR,"Unhandled format: 0x%X\n",dmpi->imgfmt); - return 0; - } - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - int best; - if(fmt!=IMGFMT_RGB1 && fmt!=IMGFMT_BGR1) return 0; - best=find_best(vf); - if(!best) return 0; // no match - return vf->next->query_format(vf->next,best); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->query_format=query_format; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - return 1; -} - -const vf_info_t vf_info_1bpp = { - "1bpp bitmap -> YUV/BGR 8/15/16/32 conversion", - "1bpp", - "A'rpi", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_2xsai.c b/libmpcodecs/vf_2xsai.c deleted file mode 100644 index dc33d9fccf..0000000000 --- a/libmpcodecs/vf_2xsai.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -//===========================================================================// - -/* FIXME: these all belong in the context, not as globals! */ - -static uint32_t colorMask = 0xF7DEF7DE; -static uint32_t lowPixelMask = 0x08210821; -static uint32_t qcolorMask = 0xE79CE79C; -static uint32_t qlowpixelMask = 0x18631863; -static uint32_t redblueMask = 0xF81F; -static uint32_t greenMask = 0x7E0; -static int PixelsPerMask = 2; - -#define makecol(r,g,b) (r+(g<<8)+(b<<16)) -#define makecol_depth(d,r,g,b) (r+(g<<8)+(b<<16)) - -static int Init_2xSaI(int d) -{ - - int minr = 0, ming = 0, minb = 0; - int i; - -// if (d != 15 && d != 16 && d != 24 && d != 32) -// return -1; - - /* Get lowest color bit */ - for (i = 0; i < 255; i++) { - if (!minr) - minr = makecol(i, 0, 0); - if (!ming) - ming = makecol(0, i, 0); - if (!minb) - minb = makecol(0, 0, i); - } - - colorMask = (makecol_depth(d, 255, 0, 0) - minr) | (makecol_depth(d, 0, 255, 0) - ming) | (makecol_depth(d, 0, 0, 255) - minb); - lowPixelMask = minr | ming | minb; - qcolorMask = (makecol_depth(d, 255, 0, 0) - 3 * minr) | (makecol_depth(d, 0, 255, 0) - 3 * ming) | (makecol_depth(d, 0, 0, 255) - 3 * minb); - qlowpixelMask = (minr * 3) | (ming * 3) | (minb * 3); - redblueMask = makecol_depth(d, 255, 0, 255); - greenMask = makecol_depth(d, 0, 255, 0); - - PixelsPerMask = (d <= 16) ? 2 : 1; - - if (PixelsPerMask == 2) { - colorMask |= (colorMask << 16); - qcolorMask |= (qcolorMask << 16); - lowPixelMask |= (lowPixelMask << 16); - qlowpixelMask |= (qlowpixelMask << 16); - } - -// TRACE("Color Mask: 0x%lX\n", colorMask); -// TRACE("Low Pixel Mask: 0x%lX\n", lowPixelMask); -// TRACE("QColor Mask: 0x%lX\n", qcolorMask); -// TRACE("QLow Pixel Mask: 0x%lX\n", qlowpixelMask); - - return 0; -} - - -#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D)) - -#define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask)) - -#define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \ - + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask) - - -static void Super2xSaI_ex(uint8_t *src, uint32_t src_pitch, - uint8_t *dst, uint32_t dst_pitch, - uint32_t width, uint32_t height, int sbpp) -{ - - unsigned int x, y; - uint32_t color[16]; - unsigned char *src_line[4]; - - /* Point to the first 3 lines. */ - src_line[0] = src; - src_line[1] = src; - src_line[2] = src + src_pitch; - src_line[3] = src + src_pitch * 2; - - x = 0, y = 0; - - if (PixelsPerMask == 2) { - unsigned short *sbp; - sbp = (unsigned short*)src_line[0]; - color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; - color[4] = color[0]; color[5] = color[0]; color[6] = *(sbp + 1); color[7] = *(sbp + 2); - sbp = (unsigned short*)src_line[2]; - color[8] = *sbp; color[9] = color[8]; color[10] = *(sbp + 1); color[11] = *(sbp + 2); - sbp = (unsigned short*)src_line[3]; - color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2); - } - else { - uint32_t *lbp; - lbp = (uint32_t*)src_line[0]; - color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; - color[4] = color[0]; color[5] = color[0]; color[6] = *(lbp + 1); color[7] = *(lbp + 2); - lbp = (uint32_t*)src_line[2]; - color[8] = *lbp; color[9] = color[8]; color[10] = *(lbp + 1); color[11] = *(lbp + 2); - lbp = (uint32_t*)src_line[3]; - color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2); - } - - for (y = 0; y < height; y++) { - unsigned char *dst_line[2]; - - dst_line[0] = dst + dst_pitch*2*y; - dst_line[1] = dst + dst_pitch*(2*y+1); - - /* Todo: x = width - 2, x = width - 1 */ - - for (x = 0; x < width; x++) { - uint32_t product1a, product1b, product2a, product2b; - -//--------------------------------------- B0 B1 B2 B3 0 1 2 3 -// 4 5* 6 S2 -> 4 5* 6 7 -// 1 2 3 S1 8 9 10 11 -// A0 A1 A2 A3 12 13 14 15 -//-------------------------------------- - if (color[9] == color[6] && color[5] != color[10]) { - product2b = color[9]; - product1b = product2b; - } - else if (color[5] == color[10] && color[9] != color[6]) { - product2b = color[5]; - product1b = product2b; - } - else if (color[5] == color[10] && color[9] == color[6]) { - int r = 0; - - r += GET_RESULT(color[6], color[5], color[8], color[13]); - r += GET_RESULT(color[6], color[5], color[4], color[1]); - r += GET_RESULT(color[6], color[5], color[14], color[11]); - r += GET_RESULT(color[6], color[5], color[2], color[7]); - - if (r > 0) - product1b = color[6]; - else if (r < 0) - product1b = color[5]; - else - product1b = INTERPOLATE(color[5], color[6]); - - product2b = product1b; - - } - else { - if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12]) - product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]); - else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15]) - product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]); - else - product2b = INTERPOLATE(color[9], color[10]); - - if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0]) - product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]); - else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3]) - product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]); - else - product1b = INTERPOLATE(color[5], color[6]); - } - - if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14]) - product2a = INTERPOLATE(color[9], color[5]); - else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12]) - product2a = INTERPOLATE(color[9], color[5]); - else - product2a = color[9]; - - if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2]) - product1a = INTERPOLATE(color[9], color[5]); - else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0]) - product1a = INTERPOLATE(color[9], color[5]); - else - product1a = color[5]; - - if (PixelsPerMask == 2) { - *((uint32_t *) (&dst_line[0][x * 4])) = product1a | (product1b << 16); - *((uint32_t *) (&dst_line[1][x * 4])) = product2a | (product2b << 16); - } - else { - *((uint32_t *) (&dst_line[0][x * 8])) = product1a; - *((uint32_t *) (&dst_line[0][x * 8 + 4])) = product1b; - *((uint32_t *) (&dst_line[1][x * 8])) = product2a; - *((uint32_t *) (&dst_line[1][x * 8 + 4])) = product2b; - } - - /* Move color matrix forward */ - color[0] = color[1]; color[4] = color[5]; color[8] = color[9]; color[12] = color[13]; - color[1] = color[2]; color[5] = color[6]; color[9] = color[10]; color[13] = color[14]; - color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15]; - - if (x < width - 3) { - x += 3; - if (PixelsPerMask == 2) { - color[3] = *(((unsigned short*)src_line[0]) + x); - color[7] = *(((unsigned short*)src_line[1]) + x); - color[11] = *(((unsigned short*)src_line[2]) + x); - color[15] = *(((unsigned short*)src_line[3]) + x); - } - else { - color[3] = *(((uint32_t*)src_line[0]) + x); - color[7] = *(((uint32_t*)src_line[1]) + x); - color[11] = *(((uint32_t*)src_line[2]) + x); - color[15] = *(((uint32_t*)src_line[3]) + x); - } - x -= 3; - } - } - - /* We're done with one line, so we shift the source lines up */ - src_line[0] = src_line[1]; - src_line[1] = src_line[2]; - src_line[2] = src_line[3]; - - /* Read next line */ - if (y + 3 >= height) - src_line[3] = src_line[2]; - else - src_line[3] = src_line[2] + src_pitch; - - /* Then shift the color matrix up */ - if (PixelsPerMask == 2) { - unsigned short *sbp; - sbp = (unsigned short*)src_line[0]; - color[0] = *sbp; color[1] = color[0]; color[2] = *(sbp + 1); color[3] = *(sbp + 2); - sbp = (unsigned short*)src_line[1]; - color[4] = *sbp; color[5] = color[4]; color[6] = *(sbp + 1); color[7] = *(sbp + 2); - sbp = (unsigned short*)src_line[2]; - color[8] = *sbp; color[9] = color[9]; color[10] = *(sbp + 1); color[11] = *(sbp + 2); - sbp = (unsigned short*)src_line[3]; - color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2); - } - else { - uint32_t *lbp; - lbp = (uint32_t*)src_line[0]; - color[0] = *lbp; color[1] = color[0]; color[2] = *(lbp + 1); color[3] = *(lbp + 2); - lbp = (uint32_t*)src_line[1]; - color[4] = *lbp; color[5] = color[4]; color[6] = *(lbp + 1); color[7] = *(lbp + 2); - lbp = (uint32_t*)src_line[2]; - color[8] = *lbp; color[9] = color[9]; color[10] = *(lbp + 1); color[11] = *(lbp + 2); - lbp = (uint32_t*)src_line[3]; - color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2); - } - - } // y loop - -} - - -//===========================================================================// - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - Init_2xSaI(outfmt&255); - - return vf_next_config(vf,2*width,2*height,2*d_width,2*d_height,flags,outfmt); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - // hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - 2*mpi->w, 2*mpi->h); - - Super2xSaI_ex(mpi->planes[0], mpi->stride[0], - dmpi->planes[0], dmpi->stride[0], - mpi->w, mpi->h, mpi->bpp/8); - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ -// case IMGFMT_BGR15: -// case IMGFMT_BGR16: - case IMGFMT_BGR32: - return vf_next_query_format(vf,fmt); - } - return 0; -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->query_format=query_format; - return 1; -} - -const vf_info_t vf_info_2xsai = { - "2xSai BGR bitmap 2x scaler", - "2xsai", - "A'rpi", - "http://elektron.its.tudelft.nl/~dalikifa/", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_blackframe.c b/libmpcodecs/vf_blackframe.c deleted file mode 100644 index 244da01be2..0000000000 --- a/libmpcodecs/vf_blackframe.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * detect frames that are (almost) black - * search for black frames to detect scene transitions - * (c) 2006 Julian Hall - * - * based on code designed for skipping commercials - * (c) 2002-2003 Brian J. Murrell - * - * cleanup, simplify, speedup (c) 2006 by Ivo van Poorten - * - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - unsigned int bamount, bthresh, frame, lastkeyframe; -}; - -static int config(struct vf_instance *vf, int width, int height, int d_width, - int d_height, unsigned int flags, unsigned int outfmt) { - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static int query_format(struct vf_instance *vf, unsigned fmt) { - switch(fmt) { - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_NV12: - case IMGFMT_NV21: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - case IMGFMT_HM12: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - int x, y; - int nblack=0, pblack=0; - unsigned char *yplane = mpi->planes[0]; - unsigned int ystride = mpi->stride[0]; - int pict_type = mpi->pict_type; - int w = mpi->w, h = mpi->h; - int bthresh = vf->priv->bthresh; - int bamount = vf->priv->bamount; - static const char *const picttypes[4] = { "unknown", "I", "P", "B" }; - - for (y=1; y<=h; y++) { - for (x=0; x 3 || pict_type < 0) pict_type = 0; - if (pict_type == 1) vf->priv->lastkeyframe = vf->priv->frame; - - if (pblack >= bamount) - mp_msg(MSGT_VFILTER, MSGL_INFO,"vf_blackframe: %u, %i%%, %s (I:%u)\n", - vf->priv->frame, pblack, picttypes[pict_type], - vf->priv->lastkeyframe); - - vf->priv->frame++; - - dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT, 0, - mpi->width, mpi->height); - dmpi->planes[0] = mpi->planes[0]; - dmpi->stride[0] = mpi->stride[0]; - dmpi->planes[1] = mpi->planes[1]; - dmpi->stride[1] = mpi->stride[1]; - dmpi->planes[2] = mpi->planes[2]; - dmpi->stride[2] = mpi->stride[2]; - - vf_clone_mpi_attributes(dmpi, mpi); - - return vf_next_put_image(vf, dmpi, pts); -} - -static int control(struct vf_instance *vf, int request, void* data){ - return vf_next_control(vf,request,data); -} - -static void uninit(struct vf_instance *vf) { - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->priv = malloc(sizeof(struct vf_priv_s)); - if (!vf->priv) return 0; - - vf->config = config; - vf->put_image = put_image; - vf->control = control; - vf->uninit = uninit; - vf->query_format = query_format; - - vf->priv->bamount = 98; - vf->priv->bthresh = 0x20; - vf->priv->frame = 0; - vf->priv->lastkeyframe = 0; - - if (args) - sscanf(args, "%u:%u", &vf->priv->bamount, &vf->priv->bthresh); - return 1; -} - -const vf_info_t vf_info_blackframe = { - "detects black frames", - "blackframe", - "Brian J. Murrell, Julian Hall, Ivo van Poorten", - "Useful for detecting scene transitions", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_bmovl.c b/libmpcodecs/vf_bmovl.c deleted file mode 100644 index da5dc97f50..0000000000 --- a/libmpcodecs/vf_bmovl.c +++ /dev/null @@ -1,496 +0,0 @@ -/* - * BitMap OVerLay video filter for MPlayer - * - * (C) 2002 Per Wigren - * - * This file is part of MPlayer. - * - * 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. - */ - -/* - * Use MPlayer as a framebuffer to read bitmaps and commands from a FIFO - * and display them in the window. - * - * Commands are: - * - * RGBA32 width height xpos ypos alpha clear - * * Followed by width*height*4 bytes of raw RGBA32 data. - * ABGR32 width height xpos ypos alpha clear - * * Followed by width*height*4 bytes of raw ABGR32 data. - * RGB24 width height xpos ypos alpha clear - * * Followed by width*height*3 bytes of raw RGB32 data. - * BGR24 width height xpos ypos alpha clear - * * Followed by width*height*3 bytes of raw BGR32 data. - * - * ALPHA width height xpos ypos alpha - * * Change alpha for area - * CLEAR width height xpos ypos - * * Clear area - * OPAQUE - * * Disable all alpha transparency! - * Send "ALPHA 0 0 0 0 0" to enable again! - * HIDE - * * Hide bitmap - * SHOW - * * Show bitmap - * - * Arguments are: - * width, height Size of image/area - * xpos, ypos Start blitting at X/Y position - * alpha Set alpha difference. 0 means same as original. - * 255 makes everything opaque - * -255 makes everything transparent - * If you set this to -255 you can then send a sequence of - * ALPHA-commands to set the area to -225, -200, -175 etc - * for a nice fade-in-effect! ;) - * clear Clear the framebuffer before blitting. 1 means clear. - * If 0, the image will just be blitted on top of the old - * one, so you don't need to send 1,8MB of RGBA32 data - * everytime a small part of the screen is updated. - * - * Arguments for the filter are hidden:opaque:fifo - * For example 1:0:/tmp/myfifo.fifo will start the filter hidden, transparent - * and use /tmp/myfifo.fifo as the fifo. - * - * If you find bugs, please send me patches! ;) - * - * This filter was developed for use in Freevo (http://freevo.sf.net), but - * anyone is free to use it! ;) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "config.h" -#include "mp_image.h" -#include "vf.h" -#include "img_format.h" - -#include "mp_msg.h" -#include "libavutil/common.h" - -#include "libvo/fastmemcpy.h" - -#define IS_RAWIMG 0x100 -#define IS_IMG 0x200 - -#define NONE 0x000 -#define IMG_RGBA32 0x101 -#define IMG_ABGR32 0x102 -#define IMG_RGB24 0x103 -#define IMG_BGR24 0x104 -#define IMG_PNG 0x201 -#define CMD_CLEAR 0x001 -#define CMD_ALPHA 0x002 - -#define TRUE 1 -#define FALSE 0 - -#define INRANGE(a,b,c) ( ((a) < (b)) ? (b) : ( ((a) > (c)) ? (c) : (a) ) ) - -#define rgb2y(R,G,B) ( (( 263*R + 516*G + 100*B) >> 10) + 16 ) -#define rgb2u(R,G,B) ( ((-152*R - 298*G + 450*B) >> 10) + 128 ) -#define rgb2v(R,G,B) ( (( 450*R - 376*G - 73*B) >> 10) + 128 ) - -#define DBG(a) (mp_msg(MSGT_VFILTER, MSGL_DBG2, "DEBUG: %d\n", a)) - -struct vf_priv_s { - int w, h, x1, y1, x2, y2; - struct { - unsigned char *y, *u, *v, *a, *oa; - } bitmap; - int stream_fd; - fd_set stream_fdset; - int opaque, hidden; -}; - -static int -query_format(struct vf_instance *vf, unsigned int fmt){ - if(fmt==IMGFMT_YV12) return VFCAP_CSP_SUPPORTED; - return 0; -} - - -static int -config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - vf->priv->bitmap.y = malloc( width*height ); - vf->priv->bitmap.u = malloc( width*height/4 ); - vf->priv->bitmap.v = malloc( width*height/4 ); - vf->priv->bitmap.a = malloc( width*height ); - vf->priv->bitmap.oa = malloc( width*height ); - if(!( vf->priv->bitmap.y && - vf->priv->bitmap.u && - vf->priv->bitmap.v && - vf->priv->bitmap.a && - vf->priv->bitmap.oa )) { - mp_msg(MSGT_VFILTER, MSGL_ERR, "vf_bmovl: Could not allocate memory for bitmap buffer: %s\n", strerror(errno) ); - return FALSE; - } - - // Set default to black... - memset( vf->priv->bitmap.u, 128, width*height/4 ); - memset( vf->priv->bitmap.v, 128, width*height/4 ); - - vf->priv->w = vf->priv->x1 = width; - vf->priv->h = vf->priv->y1 = height; - vf->priv->y2 = vf->priv->x2 = 0; - - return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt); -} - -static void -uninit(struct vf_instance *vf) -{ - if(vf->priv) { - free(vf->priv->bitmap.y); - free(vf->priv->bitmap.u); - free(vf->priv->bitmap.v); - free(vf->priv->bitmap.a); - free(vf->priv->bitmap.oa); - if (vf->priv->stream_fd >= 0) - close(vf->priv->stream_fd); - free(vf->priv); - } -} - -static int -_read_cmd(int fd, char *cmd, char *args) { - int done=FALSE, pos=0; - char tmp; - - while(!done) { - if(! read( fd, &tmp, 1 ) ) return FALSE; - if( (tmp>='A' && tmp<='Z') || (tmp>='0' && tmp<='9') ) - cmd[pos]=tmp; - else if(tmp == ' ') { - cmd[pos]='\0'; - done=TRUE; - } - else if(tmp == '\n') { - cmd[pos]='\0'; - args[0]='\0'; - return TRUE; - } - if(pos++>20) { - cmd[0]='\0'; - return TRUE; - } - } - done=FALSE; pos=0; - while(!done) { - if(! read( fd, &tmp, 1 ) ) return FALSE; - if( (tmp >= ' ') && (pos<100) ) args[pos]=tmp; - else { - args[pos]='\0'; - done=TRUE; - } - pos++; - } - return TRUE; -} - - -static int -put_image(struct vf_instance *vf, mp_image_t* mpi, double pts){ - int buf_x=0, buf_y=0, buf_pos=0; - int have, got, want; - int xpos=0, ypos=0, pos=0; - unsigned char red=0, green=0, blue=0; - mp_image_t* dmpi; - - dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->w, mpi->h); - - memcpy_pic( dmpi->planes[0], mpi->planes[0], mpi->width, mpi->height, dmpi->stride[0], mpi->stride[0] ); - memcpy_pic( dmpi->planes[1], mpi->planes[1], mpi->chroma_width, mpi->chroma_height, dmpi->stride[1], mpi->stride[1] ); - memcpy_pic( dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, dmpi->stride[2], mpi->stride[2] ); - - if(vf->priv->stream_fd >= 0) { - struct timeval tv; - int ready; - - FD_SET( vf->priv->stream_fd, &vf->priv->stream_fdset ); - tv.tv_sec=0; tv.tv_usec=0; - - ready = select( vf->priv->stream_fd+1, &vf->priv->stream_fdset, NULL, NULL, &tv ); - if(ready > 0) { - // We've got new data from the FIFO - - char cmd[20], args[100]; - int imgw,imgh,imgx,imgy,clear,imgalpha,pxsz=1,command; - unsigned char *buffer = NULL; - - if(! _read_cmd( vf->priv->stream_fd, cmd, args) ) { - mp_msg(MSGT_VFILTER, MSGL_ERR, "\nvf_bmovl: Error reading commands: %s\n\n", strerror(errno)); - return FALSE; - } - mp_msg(MSGT_VFILTER, MSGL_DBG2, "\nDEBUG: Got: %s+%s\n", cmd, args); - - command=NONE; - if ( strncmp(cmd,"RGBA32",6)==0 ) { pxsz=4; command = IMG_RGBA32; } - else if( strncmp(cmd,"ABGR32",6)==0 ) { pxsz=4; command = IMG_ABGR32; } - else if( strncmp(cmd,"RGB24" ,5)==0 ) { pxsz=3; command = IMG_RGB24; } - else if( strncmp(cmd,"BGR24" ,5)==0 ) { pxsz=3; command = IMG_BGR24; } - else if( strncmp(cmd,"CLEAR" ,5)==0 ) { pxsz=1; command = CMD_CLEAR; } - else if( strncmp(cmd,"ALPHA" ,5)==0 ) { pxsz=1; command = CMD_ALPHA; } - else if( strncmp(cmd,"OPAQUE",6)==0 ) vf->priv->opaque=TRUE; - else if( strncmp(cmd,"SHOW", 4)==0 ) vf->priv->hidden=FALSE; - else if( strncmp(cmd,"HIDE", 4)==0 ) vf->priv->hidden=TRUE; - else if( strncmp(cmd,"FLUSH" ,5)==0 ) return vf_next_put_image(vf, dmpi, pts); - else { - mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: Unknown command: '%s'. Ignoring.\n", cmd); - return vf_next_put_image(vf, dmpi, pts); - } - - if(command == CMD_ALPHA) { - sscanf( args, "%d %d %d %d %d", &imgw, &imgh, &imgx, &imgy, &imgalpha); - mp_msg(MSGT_VFILTER, MSGL_DBG2, "\nDEBUG: ALPHA: %d %d %d %d %d\n\n", - imgw, imgh, imgx, imgy, imgalpha); - if(imgw==0 && imgh==0) vf->priv->opaque=FALSE; - } - - if(command & IS_RAWIMG) { - sscanf( args, "%d %d %d %d %d %d", - &imgw, &imgh, &imgx, &imgy, &imgalpha, &clear); - mp_msg(MSGT_VFILTER, MSGL_DBG2, "\nDEBUG: RAWIMG: %d %d %d %d %d %d\n\n", - imgw, imgh, imgx, imgy, imgalpha, clear); - - buffer = malloc(imgw*imgh*pxsz); - if(!buffer) { - mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: Couldn't allocate temporary buffer! Skipping...\n\n"); - return vf_next_put_image(vf, dmpi, pts); - } - /* pipes/sockets might need multiple calls to read(): */ - want = (imgw*imgh*pxsz); - have = 0; - while (have < want) { - got = read( vf->priv->stream_fd, buffer+have, want-have ); - if (got == 0) { - mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: premature EOF...\n\n"); - break; - } - if (got < 0) { - mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: read error: %s\n\n", strerror(errno)); - break; - } - have += got; - } - mp_msg(MSGT_VFILTER, MSGL_DBG2, "Got %d bytes... (wanted %d)\n", have, want ); - - if(clear) { - memset( vf->priv->bitmap.y, 0, vf->priv->w*vf->priv->h ); - memset( vf->priv->bitmap.u, 128, vf->priv->w*vf->priv->h/4 ); - memset( vf->priv->bitmap.v, 128, vf->priv->w*vf->priv->h/4 ); - memset( vf->priv->bitmap.a, 0, vf->priv->w*vf->priv->h ); - memset( vf->priv->bitmap.oa, 0, vf->priv->w*vf->priv->h ); - vf->priv->x1 = dmpi->width; - vf->priv->y1 = dmpi->height; - vf->priv->x2 = vf->priv->y2 = 0; - } - // Define how much of our bitmap that contains graphics! - vf->priv->x1 = av_clip(imgx, 0, vf->priv->x1); - vf->priv->y1 = av_clip(imgy, 0, vf->priv->y1); - vf->priv->x2 = av_clip(imgx + imgw, vf->priv->x2, vf->priv->w); - vf->priv->y2 = av_clip(imgy + imgh, vf->priv->y2, vf->priv->h); - } - - if( command == CMD_CLEAR ) { - sscanf( args, "%d %d %d %d", &imgw, &imgh, &imgx, &imgy); - mp_msg(MSGT_VFILTER, MSGL_DBG2, "\nDEBUG: CLEAR: %d %d %d %d\n\n", imgw, imgh, imgx, imgy); - - for( ypos=imgy ; (ypos < (imgy+imgh)) && (ypos < vf->priv->y2) ; ypos++ ) { - memset( vf->priv->bitmap.y + (ypos*vf->priv->w) + imgx, 0, imgw ); - memset( vf->priv->bitmap.a + (ypos*vf->priv->w) + imgx, 0, imgw ); - memset( vf->priv->bitmap.oa + (ypos*vf->priv->w) + imgx, 0, imgw ); - if(ypos%2) { - memset( vf->priv->bitmap.u + ((ypos/2)*dmpi->stride[1]) + (imgx/2), 128, imgw/2 ); - memset( vf->priv->bitmap.v + ((ypos/2)*dmpi->stride[2]) + (imgx/2), 128, imgw/2 ); - } - } // Recalculate area that contains graphics - if( (imgx <= vf->priv->x1) && ( (imgw+imgx) >= vf->priv->x2) ) { - if( (imgy <= vf->priv->y1) && ( (imgy+imgh) >= vf->priv->y1) ) - vf->priv->y1 = imgy+imgh; - if( (imgy <= vf->priv->y2) && ( (imgy+imgh) >= vf->priv->y2) ) - vf->priv->y2 = imgy; - } - if( (imgy <= vf->priv->y1) && ( (imgy+imgh) >= vf->priv->y2) ) { - if( (imgx <= vf->priv->x1) && ( (imgx+imgw) >= vf->priv->x1) ) - vf->priv->x1 = imgx+imgw; - if( (imgx <= vf->priv->x2) && ( (imgx+imgw) >= vf->priv->x2) ) - vf->priv->x2 = imgx; - } - return vf_next_put_image(vf, dmpi, pts); - } - - for( buf_y=0 ; (buf_y < imgh) && (buf_y < (vf->priv->h-imgy)) ; buf_y++ ) { - for( buf_x=0 ; (buf_x < (imgw*pxsz)) && (buf_x < ((vf->priv->w+imgx)*pxsz)) ; buf_x += pxsz ) { - int alpha = 0xff; - - if(command & IS_RAWIMG) buf_pos = (buf_y * imgw * pxsz) + buf_x; - pos = ((buf_y+imgy) * vf->priv->w) + ((buf_x/pxsz)+imgx); - - switch(command) { - case IMG_RGBA32: - red = buffer[buf_pos+0]; - green = buffer[buf_pos+1]; - blue = buffer[buf_pos+2]; - alpha = buffer[buf_pos+3]; - break; - case IMG_ABGR32: - alpha = buffer[buf_pos+0]; - blue = buffer[buf_pos+1]; - green = buffer[buf_pos+2]; - red = buffer[buf_pos+3]; - break; - case IMG_RGB24: - red = buffer[buf_pos+0]; - green = buffer[buf_pos+1]; - blue = buffer[buf_pos+2]; - break; - case IMG_BGR24: - blue = buffer[buf_pos+0]; - green = buffer[buf_pos+1]; - red = buffer[buf_pos+2]; - break; - case CMD_ALPHA: - vf->priv->bitmap.a[pos] = INRANGE((vf->priv->bitmap.oa[pos]+imgalpha),0,255); - break; - default: - mp_msg(MSGT_VFILTER, MSGL_ERR, "vf_bmovl: Internal error!\n"); - return FALSE; - } - if( command & IS_RAWIMG ) { - vf->priv->bitmap.y[pos] = rgb2y(red,green,blue); - vf->priv->bitmap.oa[pos] = alpha; - vf->priv->bitmap.a[pos] = INRANGE((alpha+imgalpha),0,255); - if((buf_y%2) && ((buf_x/pxsz)%2)) { - pos = ( ((buf_y+imgy)/2) * dmpi->stride[1] ) + (((buf_x/pxsz)+imgx)/2); - vf->priv->bitmap.u[pos] = rgb2u(red,green,blue); - vf->priv->bitmap.v[pos] = rgb2v(red,green,blue); - } - } - } // for buf_x - } // for buf_y - free (buffer); - } else if(ready < 0) { - mp_msg(MSGT_VFILTER, MSGL_WARN, "\nvf_bmovl: Error %d in fifo: %s\n\n", errno, strerror(errno)); - } - } - - if(vf->priv->hidden) return vf_next_put_image(vf, dmpi, pts); - - if(vf->priv->opaque) { // Just copy buffer memory to screen - for( ypos=vf->priv->y1 ; ypos < vf->priv->y2 ; ypos++ ) { - fast_memcpy( dmpi->planes[0] + (ypos*dmpi->stride[0]) + vf->priv->x1, - vf->priv->bitmap.y + (ypos*vf->priv->w) + vf->priv->x1, - vf->priv->x2 - vf->priv->x1 ); - if(ypos%2) { - fast_memcpy( dmpi->planes[1] + ((ypos/2)*dmpi->stride[1]) + (vf->priv->x1/2), - vf->priv->bitmap.u + (((ypos/2)*(vf->priv->w)/2)) + (vf->priv->x1/2), - (vf->priv->x2 - vf->priv->x1)/2 ); - fast_memcpy( dmpi->planes[2] + ((ypos/2)*dmpi->stride[2]) + (vf->priv->x1/2), - vf->priv->bitmap.v + (((ypos/2)*(vf->priv->w)/2)) + (vf->priv->x1/2), - (vf->priv->x2 - vf->priv->x1)/2 ); - } - } - } else { // Blit the bitmap to the videoscreen, pixel for pixel - for( ypos=vf->priv->y1 ; ypos < vf->priv->y2 ; ypos++ ) { - for ( xpos=vf->priv->x1 ; xpos < vf->priv->x2 ; xpos++ ) { - pos = (ypos * dmpi->stride[0]) + xpos; - - int alpha = vf->priv->bitmap.a[pos]; - - if (alpha == 0) continue; // Completly transparent pixel - - if (alpha == 255) { // Opaque pixel - dmpi->planes[0][pos] = vf->priv->bitmap.y[pos]; - if ((ypos%2) && (xpos%2)) { - pos = ( (ypos/2) * dmpi->stride[1] ) + (xpos/2); - dmpi->planes[1][pos] = vf->priv->bitmap.u[pos]; - dmpi->planes[2][pos] = vf->priv->bitmap.v[pos]; - } - } else { // Alphablended pixel - dmpi->planes[0][pos] = - ((255 - alpha) * (int)dmpi->planes[0][pos] + - alpha * (int)vf->priv->bitmap.y[pos]) >> 8; - - if ((ypos%2) && (xpos%2)) { - pos = ( (ypos/2) * dmpi->stride[1] ) + (xpos/2); - - dmpi->planes[1][pos] = - ((255 - alpha) * (int)dmpi->planes[1][pos] + - alpha * (int)vf->priv->bitmap.u[pos]) >> 8; - - dmpi->planes[2][pos] = - ((255 - alpha) * (int)dmpi->planes[2][pos] + - alpha * (int)vf->priv->bitmap.v[pos]) >> 8; - } - } - } // for xpos - } // for ypos - } // if !opaque - return vf_next_put_image(vf, dmpi, pts); -} // put_image - -static int -vf_open(vf_instance_t *vf, char *args) -{ - char filename[1000]; - - vf->config = config; - vf->put_image = put_image; - vf->query_format = query_format; - vf->uninit = uninit; - - vf->priv = malloc(sizeof(struct vf_priv_s)); - - if(!args || sscanf(args, "%d:%d:%s", &vf->priv->hidden, &vf->priv->opaque, filename) < 3 ) { - mp_msg(MSGT_VFILTER, MSGL_ERR, "vf_bmovl: Bad arguments!\n"); - mp_msg(MSGT_VFILTER, MSGL_ERR, "vf_bmovl: Arguments are 'bool hidden:bool opaque:string fifo'\n"); - return FALSE; - } - - vf->priv->stream_fd = open(filename, O_RDWR); - if(vf->priv->stream_fd >= 0) { - FD_ZERO( &vf->priv->stream_fdset ); - mp_msg(MSGT_VFILTER, MSGL_INFO, "vf_bmovl: Opened fifo %s as FD %d\n", filename, vf->priv->stream_fd); - } else { - mp_msg(MSGT_VFILTER, MSGL_WARN, "vf_bmovl: Error! Couldn't open FIFO %s: %s\n", filename, strerror(errno)); - vf->priv->stream_fd = -1; - } - - return TRUE; -} - -const vf_info_t vf_info_bmovl = { - "Read bitmaps from a FIFO and display them in window", - "bmovl", - "Per Wigren", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_boxblur.c b/libmpcodecs/vf_boxblur.c deleted file mode 100644 index cc15efccf4..0000000000 --- a/libmpcodecs/vf_boxblur.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (C) 2002 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include - -#include "mp_msg.h" -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - - -//===========================================================================// - -typedef struct FilterParam{ - int radius; - int power; -}FilterParam; - -struct vf_priv_s { - FilterParam lumaParam; - FilterParam chromaParam; -}; - - -/***************************************************************************/ - - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static inline void blur(uint8_t *dst, uint8_t *src, int w, int radius, int dstStep, int srcStep){ - int x; - const int length= radius*2 + 1; - const int inv= ((1<<16) + length/2)/length; - - int sum= 0; - - for(x=0; x>16; - } - - for(; x>16; - } - - for(; x>16; - } -} - -static inline void blur2(uint8_t *dst, uint8_t *src, int w, int radius, int power, int dstStep, int srcStep){ - uint8_t temp[2][4096]; - uint8_t *a= temp[0], *b=temp[1]; - - if(radius){ - blur(a, src, w, radius, 1, srcStep); - for(; power>2; power--){ - uint8_t *c; - blur(b, a, w, radius, 1, 1); - c=a; a=b; b=c; - } - if(power>1) - blur(dst, a, w, radius, dstStep, 1); - else{ - int i; - for(i=0; iw >> mpi->chroma_x_shift; - int ch= mpi->h >> mpi->chroma_y_shift; - - mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_READABLE, - mpi->w,mpi->h); - - assert(mpi->flags&MP_IMGFLAG_PLANAR); - - hBlur(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, - dmpi->stride[0], mpi->stride[0], vf->priv->lumaParam.radius, vf->priv->lumaParam.power); - hBlur(dmpi->planes[1], mpi->planes[1], cw,ch, - dmpi->stride[1], mpi->stride[1], vf->priv->chromaParam.radius, vf->priv->chromaParam.power); - hBlur(dmpi->planes[2], mpi->planes[2], cw,ch, - dmpi->stride[2], mpi->stride[2], vf->priv->chromaParam.radius, vf->priv->chromaParam.power); - - vBlur(dmpi->planes[0], dmpi->planes[0], mpi->w,mpi->h, - dmpi->stride[0], dmpi->stride[0], vf->priv->lumaParam.radius, vf->priv->lumaParam.power); - vBlur(dmpi->planes[1], dmpi->planes[1], cw,ch, - dmpi->stride[1], dmpi->stride[1], vf->priv->chromaParam.radius, vf->priv->chromaParam.power); - vBlur(dmpi->planes[2], dmpi->planes[2], cw,ch, - dmpi->stride[2], dmpi->stride[2], vf->priv->chromaParam.radius, vf->priv->chromaParam.power); - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt) - { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_YVU9: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int vf_open(vf_instance_t *vf, char *args){ - int e; - - vf->config=config; - vf->put_image=put_image; -// vf->get_image=get_image; - vf->query_format=query_format; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - if(args==NULL) return 0; - - e=sscanf(args, "%d:%d:%d:%d", - &vf->priv->lumaParam.radius, - &vf->priv->lumaParam.power, - &vf->priv->chromaParam.radius, - &vf->priv->chromaParam.power - ); - - if(e==2){ - vf->priv->chromaParam.radius= vf->priv->lumaParam.radius; - vf->priv->chromaParam.power = vf->priv->lumaParam.power; - }else if(e!=4) - return 0; - - if(vf->priv->lumaParam.radius < 0) return 0; - if(vf->priv->chromaParam.radius < 0) return 0; - - return 1; -} - -const vf_info_t vf_info_boxblur = { - "box blur", - "boxblur", - "Michael Niedermayer", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_cropdetect.c b/libmpcodecs/vf_cropdetect.c deleted file mode 100644 index 2401db19d4..0000000000 --- a/libmpcodecs/vf_cropdetect.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - int x1,y1,x2,y2; - int limit; - int round; - int reset_count; - int fno; -}; - -static int checkline(unsigned char* src,int stride,int len,int bpp){ - int total=0; - int div=len; - switch(bpp){ - case 1: - while(--len>=0){ - total+=src[0]; src+=stride; - } - break; - case 3: - case 4: - while(--len>=0){ - total+=src[0]+src[1]+src[2]; src+=stride; - } - div*=3; - break; - } - total/=div; -// printf("total=%d\n",total); - return total; -} - -//===========================================================================// - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - vf->priv->x1=width - 1; - vf->priv->y1=height - 1; - vf->priv->x2=0; - vf->priv->y2=0; - vf->priv->fno=-2; - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - int bpp=mpi->bpp/8; - int w,h,x,y,shrink_by; - - // hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_EXPORT, 0, - mpi->w, mpi->h); - - dmpi->planes[0]=mpi->planes[0]; - dmpi->planes[1]=mpi->planes[1]; - dmpi->planes[2]=mpi->planes[2]; - dmpi->stride[0]=mpi->stride[0]; - dmpi->stride[1]=mpi->stride[1]; - dmpi->stride[2]=mpi->stride[2]; - dmpi->width=mpi->width; - dmpi->height=mpi->height; - -if(++vf->priv->fno>0){ // ignore first 2 frames - they may be empty - - // Reset the crop area every reset_count frames, if reset_count is > 0 - if(vf->priv->reset_count > 0 && vf->priv->fno > vf->priv->reset_count){ - vf->priv->x1=mpi->w-1; - vf->priv->y1=mpi->h-1; - vf->priv->x2=0; - vf->priv->y2=0; - vf->priv->fno=1; - } - - for(y=0;ypriv->y1;y++){ - if(checkline(mpi->planes[0]+mpi->stride[0]*y,bpp,mpi->w,bpp)>vf->priv->limit){ - vf->priv->y1=y; - break; - } - } - - for(y=mpi->h-1;y>vf->priv->y2;y--){ - if(checkline(mpi->planes[0]+mpi->stride[0]*y,bpp,mpi->w,bpp)>vf->priv->limit){ - vf->priv->y2=y; - break; - } - } - - for(y=0;ypriv->x1;y++){ - if(checkline(mpi->planes[0]+bpp*y,mpi->stride[0],mpi->h,bpp)>vf->priv->limit){ - vf->priv->x1=y; - break; - } - } - - for(y=mpi->w-1;y>vf->priv->x2;y--){ - if(checkline(mpi->planes[0]+bpp*y,mpi->stride[0],mpi->h,bpp)>vf->priv->limit){ - vf->priv->x2=y; - break; - } - } - - // round x and y (up), important for yuv colorspaces - // make sure they stay rounded! - x=(vf->priv->x1+1)&(~1); - y=(vf->priv->y1+1)&(~1); - - w = vf->priv->x2 - x + 1; - h = vf->priv->y2 - y + 1; - - // w and h must be divisible by 2 as well because of yuv - // colorspace problems. - if (vf->priv->round <= 1) - vf->priv->round = 16; - if (vf->priv->round % 2) - vf->priv->round *= 2; - - shrink_by = w % vf->priv->round; - w -= shrink_by; - x += (shrink_by / 2 + 1) & ~1; - - shrink_by = h % vf->priv->round; - h -= shrink_by; - y += (shrink_by / 2 + 1) & ~1; - - mp_tmsg(MSGT_VFILTER, MSGL_INFO, "[CROP] Crop area: X: %d..%d Y: %d..%d (-vf crop=%d:%d:%d:%d).\n", - vf->priv->x1,vf->priv->x2, - vf->priv->y1,vf->priv->y2, - w,h,x,y); - - -} - - return vf_next_put_image(vf,dmpi, pts); -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) { - switch(fmt) { - // the default limit value works only right with YV12 right now. - case IMGFMT_YV12: - return vf_next_query_format(vf, fmt); - } - return 0; -} -//===========================================================================// - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->query_format=query_format; - vf->priv=malloc(sizeof(struct vf_priv_s)); - vf->priv->limit=24; // should be option - vf->priv->round = 0; - vf->priv->reset_count = 0; - if(args) sscanf(args, "%d:%d:%d", - &vf->priv->limit, - &vf->priv->round, - &vf->priv->reset_count); - return 1; -} - -const vf_info_t vf_info_cropdetect = { - "autodetect crop size", - "cropdetect", - "A'rpi", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_decimate.c b/libmpcodecs/vf_decimate.c deleted file mode 100644 index 4ee78b420b..0000000000 --- a/libmpcodecs/vf_decimate.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/fastmemcpy.h" - - -struct vf_priv_s { - int hi, lo; - float frac; - int max, last, cnt; -}; - -#if HAVE_MMX && HAVE_EBX_AVAILABLE -static int diff_MMX(unsigned char *old, unsigned char *new, int os, int ns) -{ - volatile short out[4]; - __asm__ ( - "movl $8, %%ecx \n\t" - "pxor %%mm4, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - - ASMALIGN(4) - "1: \n\t" - - "movq (%%"REG_S"), %%mm0 \n\t" - "movq (%%"REG_S"), %%mm2 \n\t" - "add %%"REG_a", %%"REG_S" \n\t" - "movq (%%"REG_D"), %%mm1 \n\t" - "add %%"REG_b", %%"REG_D" \n\t" - "psubusb %%mm1, %%mm2 \n\t" - "psubusb %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm0 \n\t" - "movq %%mm1, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddw %%mm0, %%mm4 \n\t" - "paddw %%mm1, %%mm4 \n\t" - "paddw %%mm2, %%mm4 \n\t" - "paddw %%mm3, %%mm4 \n\t" - - "decl %%ecx \n\t" - "jnz 1b \n\t" - "movq %%mm4, (%%"REG_d") \n\t" - "emms \n\t" - : - : "S" (old), "D" (new), "a" ((long)os), "b" ((long)ns), "d" (out) - : "%ecx", "memory" - ); - return out[0]+out[1]+out[2]+out[3]; -} -#endif - -static int diff_C(unsigned char *old, unsigned char *new, int os, int ns) -{ - int x, y, d=0; - for (y = 8; y; y--) { - for (x = 8; x; x--) { - d += abs(new[x] - old[x]); - } - new += ns; - old += os; - } - return d; -} - -static int (*diff)(unsigned char *, unsigned char *, int, int); - -static int diff_to_drop_plane(int hi, int lo, float frac, unsigned char *old, unsigned char *new, int w, int h, int os, int ns) -{ - int x, y; - int d, c=0; - int t = (w/16)*(h/16)*frac; - for (y = 0; y < h-7; y += 4) { - for (x = 8; x < w-7; x += 4) { - d = diff(old+x+y*os, new+x+y*ns, os, ns); - if (d > hi) return 0; - if (d > lo) { - c++; - if (c > t) return 0; - } - } - } - return 1; -} - -static int diff_to_drop(int hi, int lo, float frac, mp_image_t *old, mp_image_t *new) -{ - if (new->flags & MP_IMGFLAG_PLANAR) { - return diff_to_drop_plane(hi,lo,frac, old->planes[0], new->planes[0], - new->w, new->h, old->stride[0], new->stride[0]) - && diff_to_drop_plane(hi,lo,frac, old->planes[1], new->planes[1], - new->chroma_width, new->chroma_height, - old->stride[1], new->stride[1]) - && diff_to_drop_plane(hi,lo,frac, old->planes[2], new->planes[2], - new->chroma_width, new->chroma_height, - old->stride[2], new->stride[2]); - } - return diff_to_drop_plane(hi,lo,frac, old->planes[0], new->planes[0], - new->w*(new->bpp/8), new->h, old->stride[0], new->stride[0]); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE, - mpi->width, mpi->height); - dmpi->qscale = mpi->qscale; - dmpi->qstride = mpi->qstride; - dmpi->qscale_type = mpi->qscale_type; - - if (diff_to_drop(vf->priv->hi, vf->priv->lo, vf->priv->frac, dmpi, mpi)) { - if (vf->priv->max == 0) - return 0; - else if ((vf->priv->max > 0) && (vf->priv->cnt++ < vf->priv->max)) - return 0; - else if ((vf->priv->max < 0) && (vf->priv->last+1 >= -vf->priv->max)) - return vf->priv->last=0; - } - vf->priv->last++; - vf->priv->cnt=0; - - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, - dmpi->stride[0], mpi->stride[0]); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[2], mpi->stride[2]); - } - return vf_next_put_image(vf, dmpi, pts); -} - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - struct vf_priv_s *p; - vf->put_image = put_image; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); - p->max = 0; - p->hi = 64*12; - p->lo = 64*5; - p->frac = 0.33; - if (args) sscanf(args, "%d:%d:%d:%f", &p->max, &p->hi, &p->lo, &p->frac); - diff = diff_C; -#if HAVE_MMX && HAVE_EBX_AVAILABLE - if(gCpuCaps.hasMMX) diff = diff_MMX; -#endif - return 1; -} - -const vf_info_t vf_info_decimate = { - "near-duplicate frame remover", - "decimate", - "Rich Felker", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_denoise3d.c b/libmpcodecs/vf_denoise3d.c deleted file mode 100644 index 4d1f16c8b7..0000000000 --- a/libmpcodecs/vf_denoise3d.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2003 Daniel Moreno - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include - -#include "mp_msg.h" -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#define PARAM1_DEFAULT 4.0 -#define PARAM2_DEFAULT 3.0 -#define PARAM3_DEFAULT 6.0 - -//===========================================================================// - -struct vf_priv_s { - int Coefs[4][512]; - unsigned char *Line; - mp_image_t *pmpi; -}; - - -/***************************************************************************/ - - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - free(vf->priv->Line); - vf->priv->Line = malloc(width); - vf->priv->pmpi=NULL; -// vf->default_caps &= !VFCAP_ACCEPT_STRIDE; - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv->Line); -} - -#define LowPass(Prev, Curr, Coef) (Curr + Coef[Prev - Curr]) - -static void deNoise(unsigned char *Frame, // mpi->planes[x] - unsigned char *FramePrev, // pmpi->planes[x] - unsigned char *FrameDest, // dmpi->planes[x] - unsigned char *LineAnt, // vf->priv->Line (width bytes) - int W, int H, int sStride, int pStride, int dStride, - int *Horizontal, int *Vertical, int *Temporal) -{ - int X, Y; - int sLineOffs = 0, pLineOffs = 0, dLineOffs = 0; - unsigned char PixelAnt; - - /* First pixel has no left nor top neighbor. Only previous frame */ - LineAnt[0] = PixelAnt = Frame[0]; - FrameDest[0] = LowPass(FramePrev[0], LineAnt[0], Temporal); - - /* Fist line has no top neighbor. Only left one for each pixel and - * last frame */ - for (X = 1; X < W; X++) - { - PixelAnt = LowPass(PixelAnt, Frame[X], Horizontal); - LineAnt[X] = PixelAnt; - FrameDest[X] = LowPass(FramePrev[X], LineAnt[X], Temporal); - } - - for (Y = 1; Y < H; Y++) - { - sLineOffs += sStride, pLineOffs += pStride, dLineOffs += dStride; - /* First pixel on each line doesn't have previous pixel */ - PixelAnt = Frame[sLineOffs]; - LineAnt[0] = LowPass(LineAnt[0], PixelAnt, Vertical); - FrameDest[dLineOffs] = LowPass(FramePrev[pLineOffs], LineAnt[0], Temporal); - - for (X = 1; X < W; X++) - { - /* The rest are normal */ - PixelAnt = LowPass(PixelAnt, Frame[sLineOffs+X], Horizontal); - LineAnt[X] = LowPass(LineAnt[X], PixelAnt, Vertical); - FrameDest[dLineOffs+X] = LowPass(FramePrev[pLineOffs+X], LineAnt[X], Temporal); - } - } -} - - - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - int cw= mpi->w >> mpi->chroma_x_shift; - int ch= mpi->h >> mpi->chroma_y_shift; - int W = mpi->w, H = mpi->h; - - mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_IP, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE, - mpi->w,mpi->h); - - if(!dmpi) return 0; - if (!vf->priv->pmpi) vf->priv->pmpi=mpi; - - deNoise(mpi->planes[0], vf->priv->pmpi->planes[0], dmpi->planes[0], - vf->priv->Line, W, H, - mpi->stride[0], vf->priv->pmpi->stride[0], dmpi->stride[0], - vf->priv->Coefs[0] + 256, - vf->priv->Coefs[0] + 256, - vf->priv->Coefs[1] + 256); - deNoise(mpi->planes[1], vf->priv->pmpi->planes[1], dmpi->planes[1], - vf->priv->Line, cw, ch, - mpi->stride[1], vf->priv->pmpi->stride[1], dmpi->stride[1], - vf->priv->Coefs[2] + 256, - vf->priv->Coefs[2] + 256, - vf->priv->Coefs[3] + 256); - deNoise(mpi->planes[2], vf->priv->pmpi->planes[2], dmpi->planes[2], - vf->priv->Line, cw, ch, - mpi->stride[2], vf->priv->pmpi->stride[2], dmpi->stride[2], - vf->priv->Coefs[2] + 256, - vf->priv->Coefs[2] + 256, - vf->priv->Coefs[3] + 256); - - vf->priv->pmpi=dmpi; // save reference image - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt) - { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_YVU9: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf, fmt); - } - return 0; -} - - -#define ABS(A) ( (A) > 0 ? (A) : -(A) ) - -static void PrecalcCoefs(int *Ct, double Dist25) -{ - int i; - double Gamma, Simil, C; - - Gamma = log(0.25) / log(1.0 - Dist25/255.0); - - for (i = -256; i <= 255; i++) - { - Simil = 1.0 - ABS(i) / 255.0; -// Ct[256+i] = lround(pow(Simil, Gamma) * (double)i); - C = pow(Simil, Gamma) * (double)i; - Ct[256+i] = (C<0) ? (C-0.5) : (C+0.5); - } -} - - -static int vf_open(vf_instance_t *vf, char *args){ - double LumSpac, LumTmp, ChromSpac, ChromTmp; - double Param1, Param2, Param3; - - vf->config=config; - vf->put_image=put_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - if (args) - { - switch(sscanf(args, "%lf:%lf:%lf", - &Param1, &Param2, &Param3 - )) - { - case 0: - LumSpac = PARAM1_DEFAULT; - LumTmp = PARAM3_DEFAULT; - - ChromSpac = PARAM2_DEFAULT; - ChromTmp = LumTmp * ChromSpac / LumSpac; - break; - - case 1: - LumSpac = Param1; - LumTmp = PARAM3_DEFAULT * Param1 / PARAM1_DEFAULT; - - ChromSpac = PARAM2_DEFAULT * Param1 / PARAM1_DEFAULT; - ChromTmp = LumTmp * ChromSpac / LumSpac; - break; - - case 2: - LumSpac = Param1; - LumTmp = PARAM3_DEFAULT * Param1 / PARAM1_DEFAULT; - - ChromSpac = Param2; - ChromTmp = LumTmp * ChromSpac / LumSpac; - break; - - case 3: - LumSpac = Param1; - LumTmp = Param3; - - ChromSpac = Param2; - ChromTmp = LumTmp * ChromSpac / LumSpac; - break; - - default: - LumSpac = PARAM1_DEFAULT; - LumTmp = PARAM3_DEFAULT; - - ChromSpac = PARAM2_DEFAULT; - ChromTmp = LumTmp * ChromSpac / LumSpac; - } - } - else - { - LumSpac = PARAM1_DEFAULT; - LumTmp = PARAM3_DEFAULT; - - ChromSpac = PARAM2_DEFAULT; - ChromTmp = LumTmp * ChromSpac / LumSpac; - } - - PrecalcCoefs(vf->priv->Coefs[0], LumSpac); - PrecalcCoefs(vf->priv->Coefs[1], LumTmp); - PrecalcCoefs(vf->priv->Coefs[2], ChromSpac); - PrecalcCoefs(vf->priv->Coefs[3], ChromTmp); - - return 1; -} - -const vf_info_t vf_info_denoise3d = { - "3D Denoiser (variable lowpass filter)", - "denoise3d", - "Daniel Moreno", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_detc.c b/libmpcodecs/vf_detc.c deleted file mode 100644 index bbc22fca6c..0000000000 --- a/libmpcodecs/vf_detc.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/fastmemcpy.h" - -struct metrics { - int even; - int odd; - int noise; - int temp; -}; - -struct vf_priv_s { - int frame; - int drop, lastdrop; - struct metrics pm; - int thres[5]; - int inframes, outframes; - int mode; - int (*analyze)(struct vf_priv_s *, mp_image_t *, mp_image_t *); - int needread; - struct vf_detc_pts_buf ptsbuf; -}; - -#define COMPE(a,b,e) (abs((a)-(b)) < (((a)+(b))>>(e))) -#define COMPARABLE(a,b) COMPE((a),(b),2) -#define VERYCLOSE(a,b) COMPE((a),(b),3) - -#define OUTER_TC_NBHD(s) ( \ - COMPARABLE((s)[-1].m.even,(s)[-1].m.odd) && \ - COMPARABLE((s)[1].m.even,(s)[0].m.odd) && \ - COMPARABLE((s)[2].m.even,(s)[1].m.odd) && \ - COMPARABLE((s)[-1].m.noise,(s)[0].m.temp) && \ - COMPARABLE((s)[2].m.noise,(s)[2].m.temp) ) - -#define INNER_TC_NBHD(s,l,h) ( \ - COMPARABLE((s)[0].m.even,(l)) && \ - COMPARABLE((s)[2].m.odd,(l)) && ( \ - COMPARABLE((s)[0].m.noise,(h)) || \ - COMPARABLE((s)[1].m.noise,(h)) ) ) - -enum { - TC_DROP, - TC_PROG, - TC_IL1, - TC_IL2 -}; - -static void block_diffs(struct metrics *m, unsigned char *old, unsigned char *new, int os, int ns) -{ - int x, y, even=0, odd=0, noise, temp; - unsigned char *oldp, *newp; - m->noise = m->temp = 0; - for (x = 8; x; x--) { - oldp = old++; - newp = new++; - noise = temp = 0; - for (y = 4; y; y--) { - even += abs(newp[0]-oldp[0]); - odd += abs(newp[ns]-oldp[os]); - noise += newp[ns]-newp[0]; - temp += oldp[os]-newp[0]; - oldp += os<<1; - newp += ns<<1; - } - m->noise += abs(noise); - m->temp += abs(temp); - } - m->even = even; - m->odd = odd; -} - -static void diff_planes(struct metrics *m, unsigned char *old, unsigned char *new, int w, int h, int os, int ns) -{ - int x, y, me=0, mo=0, mn=0, mt=0; - struct metrics l; - for (y = 0; y < h-7; y += 8) { - for (x = 0; x < w-7; x += 8) { - block_diffs(&l, old+x+y*os, new+x+y*ns, os, ns); - if (l.even > me) me = l.even; - if (l.odd > mo) mo = l.odd; - if (l.noise > mn) mn = l.noise; - if (l.temp > mt) mt = l.temp; - } - } - m->even = me; - m->odd = mo; - m->noise = mn; - m->temp = mt; -} - -static void diff_fields(struct metrics *metr, mp_image_t *old, mp_image_t *new) -{ - struct metrics m, mu, mv; - diff_planes(&m, old->planes[0], new->planes[0], - new->w, new->h, old->stride[0], new->stride[0]); - if (new->flags & MP_IMGFLAG_PLANAR) { - diff_planes(&mu, old->planes[1], new->planes[1], - new->chroma_width, new->chroma_height, - old->stride[1], new->stride[1]); - diff_planes(&mv, old->planes[2], new->planes[2], - new->chroma_width, new->chroma_height, - old->stride[2], new->stride[2]); - if (mu.even > m.even) m.even = mu.even; - if (mu.odd > m.odd) m.odd = mu.odd; - if (mu.noise > m.noise) m.noise = mu.noise; - if (mu.temp > m.temp) m.temp = mu.temp; - if (mv.even > m.even) m.even = mv.even; - if (mv.odd > m.odd) m.odd = mv.odd; - if (mv.noise > m.noise) m.noise = mv.noise; - if (mv.temp > m.temp) m.temp = mv.temp; - } - *metr = m; -} - -static void status(int f, struct metrics *m) -{ - mp_msg(MSGT_VFILTER, MSGL_V, "frame %d: e=%d o=%d n=%d t=%d\n", - f, m->even, m->odd, m->noise, m->temp); -} - -static int analyze_fixed_pattern(struct vf_priv_s *p, mp_image_t *new, mp_image_t *old) -{ - if (p->frame >= 0) p->frame = (p->frame+1)%5; - mp_msg(MSGT_VFILTER, MSGL_V, "frame %d\n", p->frame); - switch (p->frame) { - case -1: case 0: case 1: case 2: - return TC_PROG; - case 3: - return TC_IL1; - case 4: - return TC_IL2; - } - return 0; -} - -static int analyze_aggressive(struct vf_priv_s *p, mp_image_t *new, mp_image_t *old) -{ - struct metrics m, pm; - - if (p->frame >= 0) p->frame = (p->frame+1)%5; - - diff_fields(&m, old, new); - - status(p->frame, &m); - - pm = p->pm; - p->pm = m; - - if (p->frame == 4) { - /* We need to break at scene changes, but is this a valid test? */ - if ((m.even > p->thres[2]) && (m.odd > p->thres[2]) && (m.temp > p->thres[3]) - && (m.temp > 5*pm.temp) && (m.temp*2 > m.noise)) { - mp_msg(MSGT_VFILTER, MSGL_V, "scene change breaking telecine!\n"); - p->frame = -1; - return TC_DROP; - } - /* Thres. is to compensate for quantization errors when noise is low */ - if (m.noise - m.temp > -p->thres[4]) { - if (COMPARABLE(m.even, pm.odd)) { - //mp_msg(MSGT_VFILTER, MSGL_V, "confirmed field match!\n"); - return TC_IL2; - } else if ((m.even < p->thres[0]) && (m.odd < p->thres[0]) && VERYCLOSE(m.even, m.odd) - && VERYCLOSE(m.noise,m.temp) && VERYCLOSE(m.noise,pm.noise)) { - mp_msg(MSGT_VFILTER, MSGL_V, "interlaced frame appears in duplicate!!!\n"); - p->pm = pm; /* hack :) */ - p->frame = 3; - return TC_IL1; - } - } else { - mp_msg(MSGT_VFILTER, MSGL_V, "mismatched telecine fields!\n"); - p->frame = -1; - } - } - - if (2*m.even*m.temp < m.odd*m.noise) { - mp_msg(MSGT_VFILTER, MSGL_V, "caught telecine sync!\n"); - p->frame = 3; - return TC_IL1; - } - - if (p->frame < 3) { - if (m.noise > p->thres[3]) { - if (m.noise > 2*m.temp) { - mp_msg(MSGT_VFILTER, MSGL_V, "merging fields out of sequence!\n"); - return TC_IL2; - } - if ((m.noise > 2*pm.noise) && (m.even > p->thres[2]) && (m.odd > p->thres[2])) { - mp_msg(MSGT_VFILTER, MSGL_V, "dropping horrible interlaced frame!\n"); - return TC_DROP; - } - } - } - - switch (p->frame) { - case -1: - if (4*m.noise > 5*m.temp) { - mp_msg(MSGT_VFILTER, MSGL_V, "merging fields out of sequence!\n"); - return TC_IL2; - } - case 0: - case 1: - case 2: - return TC_PROG; - case 3: - if ((m.even > p->thres[1]) && (m.even > m.odd) && (m.temp > m.noise)) { - mp_msg(MSGT_VFILTER, MSGL_V, "lost telecine tracking!\n"); - p->frame = -1; - return TC_PROG; - } - return TC_IL1; - case 4: - return TC_IL2; - } - return 0; -} - -static void copy_image(mp_image_t *dmpi, mp_image_t *mpi, int field) -{ - switch (field) { - case 0: - my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - break; - case 1: - my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0], - mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1], - mpi->planes[1]+mpi->stride[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2], - mpi->planes[2]+mpi->stride[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - break; - case 2: - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, - dmpi->stride[0], mpi->stride[0]); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[2], mpi->stride[2]); - } - break; - } -} - -static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi, double pts) -{ - struct vf_priv_s *p = vf->priv; - int dropflag; - - switch (p->drop) { - default: - dropflag = 0; - break; - case 1: - dropflag = (++p->lastdrop >= 5); - break; - case 2: - dropflag = (++p->lastdrop >= 5) && (4*p->inframes <= 5*p->outframes); - break; - } - - if (dropflag) { - mp_msg(MSGT_VFILTER, MSGL_V, "drop! [%d/%d=%g]\n", - p->outframes, p->inframes, (float)p->outframes/p->inframes); - p->lastdrop = 0; - vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1); - return 0; - } - - p->outframes++; - return vf_next_put_image(vf, dmpi, vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 0)); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - int ret=0; - mp_image_t *dmpi; - struct vf_priv_s *p = vf->priv; - - p->inframes++; - - if (p->needread) dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE, - mpi->width, mpi->height); - /* FIXME: is there a good way to get rid of static type? */ - else dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE, mpi->width, mpi->height); - - switch (p->analyze(p, mpi, dmpi)) { - case TC_DROP: - /* Don't copy anything unless we'll need to read it. */ - if (p->needread) copy_image(dmpi, mpi, 2); - p->lastdrop = 0; - vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1); - break; - case TC_PROG: - /* Copy and display the whole frame. */ - copy_image(dmpi, mpi, 2); - ret = do_put_image(vf, dmpi, pts); - break; - case TC_IL1: - /* Only copy bottom field unless we need to read. */ - if (p->needread) copy_image(dmpi, mpi, 2); - else copy_image(dmpi, mpi, 1); - p->lastdrop = 0; - vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1); - break; - case TC_IL2: - /* Copy top field and show frame, then copy bottom if needed. */ - copy_image(dmpi, mpi, 0); - ret = do_put_image(vf, dmpi, pts); - if (p->needread) copy_image(dmpi, mpi, 1); - break; - } - return ret; -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - /* FIXME - figure out which other formats work */ - switch (fmt) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static struct { - char *name; - int (*func)(struct vf_priv_s *p, mp_image_t *new, mp_image_t *old); - int needread; -} anal_funcs[] = { - { "fixed", analyze_fixed_pattern, 0 }, - { "aggressive", analyze_aggressive, 1 }, - { NULL, NULL, 0 } -}; - -#define STARTVARS if (0) -#define GETVAR(str, name, out, func) \ - else if (!strncmp((str), name "=", sizeof(name))) \ - (out) = (func)((str) + sizeof(name)) - -static void parse_var(struct vf_priv_s *p, char *var) -{ - STARTVARS; - GETVAR(var, "dr", p->drop, atoi); - GETVAR(var, "t0", p->thres[0], atoi); - GETVAR(var, "t1", p->thres[1], atoi); - GETVAR(var, "t2", p->thres[2], atoi); - GETVAR(var, "t3", p->thres[3], atoi); - GETVAR(var, "t4", p->thres[4], atoi); - GETVAR(var, "fr", p->frame, atoi); - GETVAR(var, "am", p->mode, atoi); -} - -static void parse_args(struct vf_priv_s *p, char *args) -{ - char *next, *orig; - for (args=orig=strdup(args); args; args=next) { - next = strchr(args, ':'); - if (next) *next++ = 0; - parse_var(p, args); - } - free(orig); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - struct vf_priv_s *p; - vf->config = config; - vf->put_image = put_image; - vf->query_format = query_format; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); - p->frame = -1; - p->thres[0] = 440; - p->thres[1] = 720; - p->thres[2] = 2500; - p->thres[3] = 2500; - p->thres[4] = 800; - p->drop = 0; - p->mode = 1; - if (args) parse_args(p, args); - p->analyze = anal_funcs[p->mode].func; - p->needread = anal_funcs[p->mode].needread; - vf_detc_init_pts_buf(&p->ptsbuf); - return 1; -} - -const vf_info_t vf_info_detc = { - "de-telecine filter", - "detc", - "Rich Felker", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_dint.c b/libmpcodecs/vf_dint.c deleted file mode 100644 index b449f9292c..0000000000 --- a/libmpcodecs/vf_dint.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "mp_image.h" -#include "img_format.h" -#include "vf.h" - -struct vf_priv_s { - float sense; // first parameter - float level; // second parameter - unsigned int imgfmt; - int diff; - uint32_t max; -// int dfr; -// int rdfr; - int was_dint; - mp_image_t *pmpi; // previous mpi -}; - -#define MAXROWSIZE 1200 - -static int config (struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - int rowsize; - - vf->priv->pmpi = vf_get_image (vf->next, outfmt, MP_IMGTYPE_TEMP, - 0, width, height); - if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) && - outfmt != IMGFMT_RGB32 && outfmt != IMGFMT_BGR32 && - outfmt != IMGFMT_RGB24 && outfmt != IMGFMT_BGR24 && - outfmt != IMGFMT_RGB16 && outfmt != IMGFMT_BGR16) - { - mp_msg (MSGT_VFILTER, MSGL_WARN, "Drop-interlaced filter doesn't support this outfmt :(\n"); - return 0; - } - vf->priv->imgfmt = outfmt; - // recalculate internal values - rowsize = vf->priv->pmpi->width; - if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE; - vf->priv->max = vf->priv->level * vf->priv->pmpi->height * rowsize / 2; - if (vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) // planar YUV - vf->priv->diff = vf->priv->sense * 256; - else - vf->priv->diff = vf->priv->sense * (1 << (vf->priv->pmpi->bpp/3)); - if (vf->priv->diff < 0) vf->priv->diff = 0; - if (!(vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) && - vf->priv->pmpi->bpp < 24 && vf->priv->diff > 31) - vf->priv->diff = 31; - mp_msg (MSGT_VFILTER, MSGL_INFO, "Drop-interlaced: %dx%d diff %d / level %u\n", - vf->priv->pmpi->width, vf->priv->pmpi->height, - vf->priv->diff, (unsigned int)vf->priv->max); -// vf->priv->rdfr = vf->priv->dfr = 0; - vf->priv->was_dint = 0; - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - int8_t rrow0[MAXROWSIZE]; - int8_t rrow1[MAXROWSIZE]; - int8_t rrow2[MAXROWSIZE]; - int8_t *row0 = rrow0, *row1 = rrow1, *row2 = rrow2/*, *row3 = rrow3*/; - int rowsize = mpi->width; - uint32_t nok = 0, max = vf->priv->max; - int diff = vf->priv->diff; - int i, j; - register int n1, n2; - unsigned char *cur0, *prv0; - register unsigned char *cur, *prv; - - if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE; - // check if nothing to do - if (mpi->imgfmt == vf->priv->imgfmt) - { - cur0 = mpi->planes[0] + mpi->stride[0]; - prv0 = mpi->planes[0]; - for (j = 1; j < mpi->height && nok <= max; j++) - { - cur = cur0; - prv = prv0; - // analyse row (row0) - if (mpi->flags & MP_IMGFLAG_PLANAR) // planar YUV - check luminance - for (i = 0; i < rowsize; i++) - { - if (cur[0] - prv[0] > diff) - row0[i] = 1; - else if (cur[0] - prv[0] < -diff) - row0[i] = -1; - else - row0[i] = 0; - cur++; - prv++; - // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0 - // but row3 is 1 so it's interlaced ptr (nok++) - if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) && - (++nok) > max) - break; - } - else if (mpi->bpp < 24) // RGB/BGR 16 - check all colors - for (i = 0; i < rowsize; i++) - { - n1 = cur[0] + (cur[1]<<8); - n2 = prv[0] + (prv[1]<<8); - if ((n1&0x1f) - (n2&0x1f) > diff || - ((n1>>5)&0x3f) - ((n2>>5)&0x3f) > diff || - ((n1>>11)&0x1f) - ((n2>>11)&0x1f) > diff) - row0[i] = 1; - else if ((n1&0x1f) - (n2&0x1f) < -diff || - ((n1>>5)&0x3f) - ((n2>>5)&0x3f) < -diff || - ((n1>>11)&0x1f) - ((n2>>11)&0x1f) < -diff) - row0[i] = -1; - else - row0[i] = 0; - cur += 2; - prv += 2; - // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0 - // but row3 is 1 so it's interlaced ptr (nok++) - if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) && - (++nok) > max) - break; - } - else // RGB/BGR 24/32 - for (i = 0; i < rowsize; i++) - { - if (cur[0] - prv[0] > diff || - cur[1] - prv[1] > diff || - cur[2] - prv[2] > diff) - row0[i] = 1; - else if (prv[0] - cur[0] > diff || - prv[1] - cur[1] > diff || - prv[2] - cur[2] > diff) - row0[i] = -1; - else - row0[i] = 0; - cur += mpi->bpp/8; - prv += mpi->bpp/8; - // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0 - // but row3 is 1 so it's interlaced ptr (nok++) - if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) && - (++nok) > max) - break; - } - cur0 += mpi->stride[0]; - prv0 += mpi->stride[0]; - // rotate rows - cur = row2; - row2 = row1; - row1 = row0; - row0 = cur; - } - } - // check if number of interlaced is above of max - if (nok > max) - { -// vf->priv->dfr++; - if (vf->priv->was_dint < 1) // can skip at most one frame! - { - vf->priv->was_dint++; -// vf->priv->rdfr++; -// mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr); - return 0; - } - } - vf->priv->was_dint = 0; -// mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr); - return vf_next_put_image (vf, mpi, pts); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config = config; - vf->put_image = put_image; -// vf->default_reqs=VFCAP_ACCEPT_STRIDE; - vf->priv = malloc (sizeof(struct vf_priv_s)); - vf->priv->sense = 0.1; - vf->priv->level = 0.15; - vf->priv->pmpi = NULL; - if (args) - sscanf (args, "%f:%f", &vf->priv->sense, &vf->priv->level); - return 1; -} - -const vf_info_t vf_info_dint = { - "drop interlaced frames", - "dint", - "A.G.", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_dvbscale.c b/libmpcodecs/vf_dvbscale.c deleted file mode 100644 index 00c54ccbdf..0000000000 --- a/libmpcodecs/vf_dvbscale.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - int aspect; -}; - -//===========================================================================// - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - int scaled_y=vf->priv->aspect*d_height/d_width; - - d_width=width; // do X-scaling by hardware - d_height=scaled_y; - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->default_caps=0; - vf->priv=malloc(sizeof(struct vf_priv_s)); - vf->priv->aspect=768; - if(args) vf->priv->aspect=atoi(args); - return 1; -} - -const vf_info_t vf_info_dvbscale = { - "calc Y scaling for DVB card", - "dvbscale", - "A'rpi", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_eq.c b/libmpcodecs/vf_eq.c deleted file mode 100644 index 5925c86451..0000000000 --- a/libmpcodecs/vf_eq.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/video_out.h" - -#include "m_option.h" -#include "m_struct.h" - -static struct vf_priv_s { - unsigned char *buf; - int brightness; - int contrast; -} const vf_priv_dflt = { - NULL, - 0, - 0 -}; - -#if HAVE_MMX -static void process_MMX(unsigned char *dest, int dstride, unsigned char *src, int sstride, - int w, int h, int brightness, int contrast) -{ - int i; - int pel; - int dstep = dstride-w; - int sstep = sstride-w; - short brvec[4]; - short contvec[4]; - - contrast = ((contrast+100)*256*16)/100; - brightness = ((brightness+100)*511)/200-128 - contrast/32; - - brvec[0] = brvec[1] = brvec[2] = brvec[3] = brightness; - contvec[0] = contvec[1] = contvec[2] = contvec[3] = contrast; - - while (h--) { - __asm__ volatile ( - "movq (%5), %%mm3 \n\t" - "movq (%6), %%mm4 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "movl %4, %%eax\n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%0), %%mm1 \n\t" - "movq (%0), %%mm2 \n\t" - "punpcklbw %%mm0, %%mm1 \n\t" - "punpckhbw %%mm0, %%mm2 \n\t" - "psllw $4, %%mm1 \n\t" - "psllw $4, %%mm2 \n\t" - "pmulhw %%mm4, %%mm1 \n\t" - "pmulhw %%mm4, %%mm2 \n\t" - "paddw %%mm3, %%mm1 \n\t" - "paddw %%mm3, %%mm2 \n\t" - "packuswb %%mm2, %%mm1 \n\t" - "add $8, %0 \n\t" - "movq %%mm1, (%1) \n\t" - "add $8, %1 \n\t" - "decl %%eax \n\t" - "jnz 1b \n\t" - : "=r" (src), "=r" (dest) - : "0" (src), "1" (dest), "r" (w>>3), "r" (brvec), "r" (contvec) - : "%eax" - ); - - for (i = w&7; i; i--) - { - pel = ((*src++* contrast)>>12) + brightness; - if(pel&768) pel = (-pel)>>31; - *dest++ = pel; - } - - src += sstep; - dest += dstep; - } - __asm__ volatile ( "emms \n\t" ::: "memory" ); -} -#endif - -static void process_C(unsigned char *dest, int dstride, unsigned char *src, int sstride, - int w, int h, int brightness, int contrast) -{ - int i; - int pel; - int dstep = dstride-w; - int sstep = sstride-w; - - contrast = ((contrast+100)*256*256)/100; - brightness = ((brightness+100)*511)/200-128 - contrast/512; - - while (h--) { - for (i = w; i; i--) - { - pel = ((*src++* contrast)>>16) + brightness; - if(pel&768) pel = (-pel)>>31; - *dest++ = pel; - } - src += sstep; - dest += dstep; - } -} - -static void (*process)(unsigned char *dest, int dstride, unsigned char *src, int sstride, - int w, int h, int brightness, int contrast); - -/* FIXME: add packed yuv version of process */ - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - - dmpi=vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_EXPORT, 0, - mpi->w, mpi->h); - - dmpi->stride[0] = mpi->stride[0]; - dmpi->planes[1] = mpi->planes[1]; - dmpi->planes[2] = mpi->planes[2]; - dmpi->stride[1] = mpi->stride[1]; - dmpi->stride[2] = mpi->stride[2]; - - if (!vf->priv->buf) vf->priv->buf = malloc(mpi->stride[0]*mpi->h); - - if ((vf->priv->brightness == 0) && (vf->priv->contrast == 0)) - dmpi->planes[0] = mpi->planes[0]; - else { - dmpi->planes[0] = vf->priv->buf; - process(dmpi->planes[0], dmpi->stride[0], - mpi->planes[0], mpi->stride[0], - mpi->w, mpi->h, vf->priv->brightness, - vf->priv->contrast); - } - - return vf_next_put_image(vf,dmpi, pts); -} - -static int control(struct vf_instance *vf, int request, void* data) -{ - vf_equalizer_t *eq; - - switch (request) { - case VFCTRL_SET_EQUALIZER: - eq = data; - if (!strcmp(eq->item,"brightness")) { - vf->priv->brightness = eq->value; - return CONTROL_TRUE; - } - else if (!strcmp(eq->item,"contrast")) { - vf->priv->contrast = eq->value; - return CONTROL_TRUE; - } - break; - case VFCTRL_GET_EQUALIZER: - eq = data; - if (!strcmp(eq->item,"brightness")) { - eq->value = vf->priv->brightness; - return CONTROL_TRUE; - } - else if (!strcmp(eq->item,"contrast")) { - eq->value = vf->priv->contrast; - return CONTROL_TRUE; - } - break; - } - return vf_next_control(vf, request, data); -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - switch (fmt) { - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_NV12: - case IMGFMT_NV21: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv->buf); - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - vf->control=control; - vf->query_format=query_format; - vf->put_image=put_image; - vf->uninit=uninit; - - process = process_C; -#if HAVE_MMX - if(gCpuCaps.hasMMX) process = process_MMX; -#endif - - return 1; -} - -#define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) -static const m_option_t vf_opts_fields[] = { - {"brightness", ST_OFF(brightness), CONF_TYPE_INT, M_OPT_RANGE,-100 ,100, NULL}, - {"contrast", ST_OFF(contrast), CONF_TYPE_INT, M_OPT_RANGE,-100 ,100, NULL}, - { NULL, NULL, 0, 0, 0, 0, NULL } -}; - -static const m_struct_t vf_opts = { - "eq", - sizeof(struct vf_priv_s), - &vf_priv_dflt, - vf_opts_fields -}; - -const vf_info_t vf_info_eq = { - "soft video equalizer", - "eq", - "Richard Felker", - "", - vf_open, - &vf_opts -}; diff --git a/libmpcodecs/vf_field.c b/libmpcodecs/vf_field.c deleted file mode 100644 index f9cb06aded..0000000000 --- a/libmpcodecs/vf_field.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - int field; -}; - -//===========================================================================// - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - return vf_next_config(vf,width,height/2,d_width,d_height,flags,outfmt); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->width, mpi->height/2); - - // set up mpi as a double-stride image of dmpi: - vf->dmpi->planes[0]=mpi->planes[0]+mpi->stride[0]*vf->priv->field; - vf->dmpi->stride[0]=2*mpi->stride[0]; - if(vf->dmpi->flags&MP_IMGFLAG_PLANAR){ - vf->dmpi->planes[1]=mpi->planes[1]+ - mpi->stride[1]*vf->priv->field; - vf->dmpi->stride[1]=2*mpi->stride[1]; - vf->dmpi->planes[2]=mpi->planes[2]+ - mpi->stride[2]*vf->priv->field; - vf->dmpi->stride[2]=2*mpi->stride[2]; - } else - vf->dmpi->planes[1]=mpi->planes[1]; // passthru bgr8 palette!!! - - return vf_next_put_image(vf,vf->dmpi, pts); -} - -//===========================================================================// - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->uninit=uninit; - vf->default_reqs=VFCAP_ACCEPT_STRIDE; - vf->priv=calloc(1, sizeof(struct vf_priv_s)); - if (args) sscanf(args, "%d", &vf->priv->field); - vf->priv->field &= 1; - return 1; -} - -const vf_info_t vf_info_field = { - "extract single field", - "field", - "Rich Felker", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_fil.c b/libmpcodecs/vf_fil.c deleted file mode 100644 index fb04f9504b..0000000000 --- a/libmpcodecs/vf_fil.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - int interleave; - int height; - int width; - int stridefactor; -}; - -//===========================================================================// - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - int pixel_stride= (width+15)&~15; //FIXME this is ust a guess ... especially for non planar its somewhat bad one - -#if 0 - if(mpi->flags&MP_IMGFLAG_PLANAR) - pixel_stride= mpi->stride[0]; - else - pixel_stride= 8*mpi->stride[0] / mpi->bpp; - -#endif - - if(vf->priv->interleave){ - vf->priv->height= 2*height; - vf->priv->width= width - (pixel_stride/2); - vf->priv->stridefactor=1; - }else{ - vf->priv->height= height/2; - vf->priv->width= width + pixel_stride; - vf->priv->stridefactor=4; - } -//printf("hX %d %d %d\n", vf->priv->width,vf->priv->height,vf->priv->stridefactor); - - return vf_next_config(vf, vf->priv->width, vf->priv->height, - (d_width*vf->priv->stridefactor)>>1, 2*d_height/vf->priv->stridefactor, flags, outfmt); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - if(mpi->flags&MP_IMGFLAG_DIRECT){ - // we've used DR, so we're ready... - return vf_next_put_image(vf,(mp_image_t*)mpi->priv, pts); - } - - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE, - vf->priv->width, vf->priv->height); - - // set up mpi as a double-stride image of dmpi: - vf->dmpi->planes[0]=mpi->planes[0]; - vf->dmpi->stride[0]=(mpi->stride[0]*vf->priv->stridefactor)>>1; - if(vf->dmpi->flags&MP_IMGFLAG_PLANAR){ - vf->dmpi->planes[1]=mpi->planes[1]; - vf->dmpi->stride[1]=(mpi->stride[1]*vf->priv->stridefactor)>>1; - vf->dmpi->planes[2]=mpi->planes[2]; - vf->dmpi->stride[2]=(mpi->stride[2]*vf->priv->stridefactor)>>1; - } else - vf->dmpi->planes[1]=mpi->planes[1]; // passthru bgr8 palette!!! - - return vf_next_put_image(vf,vf->dmpi, pts); -} - -//===========================================================================// - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->uninit=uninit; - vf->default_reqs=VFCAP_ACCEPT_STRIDE; - vf->priv=calloc(1, sizeof(struct vf_priv_s)); - vf->priv->interleave= args && (*args == 'i'); - return 1; -} - -const vf_info_t vf_info_fil = { - "fast (de)interleaver", - "fil", - "Michael Niedermayer", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_filmdint.c b/libmpcodecs/vf_filmdint.c deleted file mode 100644 index 28eb1e77af..0000000000 --- a/libmpcodecs/vf_filmdint.c +++ /dev/null @@ -1,1442 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" -#include "options.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "cmmx.h" - -#include "libvo/fastmemcpy.h" - -#define NUM_STORED 4 - -enum pu_field_type_t { - PU_1ST_OF_3, - PU_2ND_OF_3, - PU_3RD_OF_3, - PU_1ST_OF_2, - PU_2ND_OF_2, - PU_INTERLACED -}; - -struct metrics { - /* This struct maps to a packed word 64-bit MMX register */ - unsigned short int even; - unsigned short int odd; - unsigned short int noise; - unsigned short int temp; -} __attribute__ ((aligned (8))); - -struct frame_stats { - struct metrics tiny, low, high, bigger, twox, max; - struct { unsigned int even, odd, noise, temp; } sad; - unsigned short interlaced_high; - unsigned short interlaced_low; - unsigned short num_blocks; -}; - -struct vf_priv_s { - unsigned long inframes; - unsigned long outframes; - enum pu_field_type_t prev_type; - unsigned swapped, chroma_swapped; - unsigned luma_only; - unsigned verbose; - unsigned fast; - unsigned long w, h, cw, ch, stride, chroma_stride, nplanes; - unsigned long sad_thres; - unsigned long dint_thres; - unsigned char *memory_allocated; - unsigned char *planes[2*NUM_STORED][4]; - unsigned char **old_planes; - unsigned long static_idx; - unsigned long temp_idx; - unsigned long crop_x, crop_y, crop_cx, crop_cy; - unsigned long export_count, merge_count; - unsigned long num_breaks; - unsigned long num_copies; - long in_inc, out_dec, iosync; - long num_fields; - long prev_fields; - long notout; - long mmx2; - unsigned small_bytes[2]; - unsigned mmx_temp[2]; - struct frame_stats stats[2]; - struct metrics thres; - char chflag; - double diff_time, merge_time, decode_time, vo_time, filter_time; - struct vf_detc_pts_buf ptsbuf; -}; - -#define PPZ { 2000, 2000, 0, 2000 } -#define PPR { 2000, 2000, 0, 2000 } -static const struct frame_stats ppzs = {PPZ,PPZ,PPZ,PPZ,PPZ,PPZ,PPZ,0,0,9999}; -static const struct frame_stats pprs = {PPR,PPR,PPR,PPR,PPR,PPR,PPR,0,0,9999}; - -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif - -#define PDIFFUB(X,Y,T) "movq " #X "," #T "\n\t" \ - "psubusb " #Y "," #T "\n\t" \ - "psubusb " #X "," #Y "\n\t" \ - "paddusb " #Y "," #T "\n\t" - -#define PDIFFUBT(X,Y,T) "movq " #X "," #T "\n\t" \ - "psubusb " #Y "," #T "\n\t" \ - "psubusb " #X "," #Y "\n\t" \ - "paddusb " #T "," #Y "\n\t" - -#define PSUMBW(X,T,Z) "movq " #X "," #T "\n\t" \ - "punpcklbw " #Z "," #X "\n\t" \ - "punpckhbw " #Z "," #T "\n\t" \ - "paddw " #T "," #X "\n\t" \ - "movq " #X "," #T "\n\t" \ - "psllq $32, " #T "\n\t" \ - "paddw " #T "," #X "\n\t" \ - "movq " #X "," #T "\n\t" \ - "psllq $16, " #T "\n\t" \ - "paddw " #T "," #X "\n\t" \ - "psrlq $48, " #X "\n\t" - -#define PSADBW(X,Y,T,Z) PDIFFUBT(X,Y,T) PSUMBW(Y,T,Z) - -#define PMAXUB(X,Y) "psubusb " #X "," #Y "\n\tpaddusb " #X "," #Y "\n\t" -#define PMAXUW(X,Y) "psubusw " #X "," #Y "\n\tpaddusw " #X "," #Y "\n\t" -#define PMINUBT(X,Y,T) "movq " #Y "," #T "\n\t" \ - "psubusb " #X "," #T "\n\t" \ - "psubusb " #T "," #Y "\n\t" -#define PAVGB(X,Y) "pavgusb " #X "," #Y "\n\t" - -static inline void -get_metrics_c(unsigned char *a, unsigned char *b, int as, int bs, int lines, - struct metrics *m) -{ - a -= as; - b -= bs; - do { - cmmx_t old_po = *(cmmx_t*)(a ); - cmmx_t po = *(cmmx_t*)(b ); - cmmx_t e = *(cmmx_t*)(b + bs); - cmmx_t old_o = *(cmmx_t*)(a + 2*as); - cmmx_t o = *(cmmx_t*)(b + 2*bs); - cmmx_t ne = *(cmmx_t*)(b + 3*bs); - cmmx_t old_no = *(cmmx_t*)(a + 4*as); - cmmx_t no = *(cmmx_t*)(b + 4*bs); - - cmmx_t qup_old_odd = p31avgb(old_o, old_po); - cmmx_t qup_odd = p31avgb( o, po); - cmmx_t qdown_old_odd = p31avgb(old_o, old_no); - cmmx_t qdown_odd = p31avgb( o, no); - - cmmx_t qup_even = p31avgb(ne, e); - cmmx_t qdown_even = p31avgb(e, ne); - - cmmx_t temp_up_diff = pdiffub(qdown_even, qup_old_odd); - cmmx_t noise_up_diff = pdiffub(qdown_even, qup_odd); - cmmx_t temp_down_diff = pdiffub(qup_even, qdown_old_odd); - cmmx_t noise_down_diff = pdiffub(qup_even, qdown_odd); - - cmmx_t odd_diff = pdiffub(o, old_o); - m->odd += psumbw(odd_diff); - m->even += psadbw(e, *(cmmx_t*)(a+as)); - - temp_up_diff = pminub(temp_up_diff, temp_down_diff); - temp_up_diff = pminub(temp_up_diff, odd_diff); - m->temp += psumbw(temp_up_diff); - noise_up_diff = pminub(noise_up_diff, odd_diff); - noise_up_diff = pminub(noise_up_diff, noise_down_diff); - - m->noise += psumbw(noise_up_diff); - a += 2*as; - b += 2*bs; - } while (--lines); -} - -static inline void -get_metrics_fast_c(unsigned char *a, unsigned char *b, int as, int bs, - int lines, struct metrics *m) -{ - a -= as; - b -= bs; - do { - cmmx_t old_po = (*(cmmx_t*)(a ) >> 1) & ~SIGN_BITS; - cmmx_t po = (*(cmmx_t*)(b ) >> 1) & ~SIGN_BITS; - cmmx_t old_e = (*(cmmx_t*)(a + as) >> 1) & ~SIGN_BITS; - cmmx_t e = (*(cmmx_t*)(b + bs) >> 1) & ~SIGN_BITS; - cmmx_t old_o = (*(cmmx_t*)(a + 2*as) >> 1) & ~SIGN_BITS; - cmmx_t o = (*(cmmx_t*)(b + 2*bs) >> 1) & ~SIGN_BITS; - cmmx_t ne = (*(cmmx_t*)(b + 3*bs) >> 1) & ~SIGN_BITS; - cmmx_t old_no = (*(cmmx_t*)(a + 4*as) >> 1) & ~SIGN_BITS; - cmmx_t no = (*(cmmx_t*)(b + 4*bs) >> 1) & ~SIGN_BITS; - - cmmx_t qup_old_odd = p31avgb_s(old_o, old_po); - cmmx_t qup_odd = p31avgb_s( o, po); - cmmx_t qdown_old_odd = p31avgb_s(old_o, old_no); - cmmx_t qdown_odd = p31avgb_s( o, no); - - cmmx_t qup_even = p31avgb_s(ne, e); - cmmx_t qdown_even = p31avgb_s(e, ne); - - cmmx_t temp_up_diff = pdiffub_s(qdown_even, qup_old_odd); - cmmx_t noise_up_diff = pdiffub_s(qdown_even, qup_odd); - cmmx_t temp_down_diff = pdiffub_s(qup_even, qdown_old_odd); - cmmx_t noise_down_diff = pdiffub_s(qup_even, qdown_odd); - - cmmx_t odd_diff = pdiffub_s(o, old_o); - m->odd += psumbw_s(odd_diff) << 1; - m->even += psadbw_s(e, old_e) << 1; - - temp_up_diff = pminub_s(temp_up_diff, temp_down_diff); - temp_up_diff = pminub_s(temp_up_diff, odd_diff); - m->temp += psumbw_s(temp_up_diff) << 1; - noise_up_diff = pminub_s(noise_up_diff, odd_diff); - noise_up_diff = pminub_s(noise_up_diff, noise_down_diff); - - m->noise += psumbw_s(noise_up_diff) << 1; - a += 2*as; - b += 2*bs; - } while (--lines); -} - -static inline void -get_metrics_faster_c(unsigned char *a, unsigned char *b, int as, int bs, - int lines, struct metrics *m) -{ - a -= as; - b -= bs; - do { - cmmx_t old_po = (*(cmmx_t*)(a )>>1) & ~SIGN_BITS; - cmmx_t po = (*(cmmx_t*)(b )>>1) & ~SIGN_BITS; - cmmx_t old_e = (*(cmmx_t*)(a + as)>>1) & ~SIGN_BITS; - cmmx_t e = (*(cmmx_t*)(b + bs)>>1) & ~SIGN_BITS; - cmmx_t old_o = (*(cmmx_t*)(a + 2*as)>>1) & ~SIGN_BITS; - cmmx_t o = (*(cmmx_t*)(b + 2*bs)>>1) & ~SIGN_BITS; - cmmx_t ne = (*(cmmx_t*)(b + 3*bs)>>1) & ~SIGN_BITS; - - cmmx_t down_even = p31avgb_s(e, ne); - cmmx_t up_odd = p31avgb_s(o, po); - cmmx_t up_old_odd = p31avgb_s(old_o, old_po); - - cmmx_t odd_diff = pdiffub_s(o, old_o); - cmmx_t temp_diff = pdiffub_s(down_even, up_old_odd); - cmmx_t noise_diff = pdiffub_s(down_even, up_odd); - - m->even += psadbw_s(e, old_e) << 1; - m->odd += psumbw_s(odd_diff) << 1; - - temp_diff = pminub_s(temp_diff, odd_diff); - noise_diff = pminub_s(noise_diff, odd_diff); - - m->noise += psumbw_s(noise_diff) << 1; - m->temp += psumbw_s(temp_diff) << 1; - a += 2*as; - b += 2*bs; - } while (--lines); - -} - -static inline void -get_block_stats(struct metrics *m, struct vf_priv_s *p, struct frame_stats *s) -{ - unsigned two_e = m->even + MAX(m->even , p->thres.even ); - unsigned two_o = m->odd + MAX(m->odd , p->thres.odd ); - unsigned two_n = m->noise + MAX(m->noise, p->thres.noise); - unsigned two_t = m->temp + MAX(m->temp , p->thres.temp ); - - unsigned e_big = m->even >= (m->odd + two_o + 1)/2; - unsigned o_big = m->odd >= (m->even + two_e + 1)/2; - unsigned n_big = m->noise >= (m->temp + two_t + 1)/2; - unsigned t_big = m->temp >= (m->noise + two_n + 1)/2; - - unsigned e2x = m->even >= two_o; - unsigned o2x = m->odd >= two_e; - unsigned n2x = m->noise >= two_t; - unsigned t2x = m->temp >= two_n; - - unsigned ntiny_e = m->even > p->thres.even ; - unsigned ntiny_o = m->odd > p->thres.odd ; - unsigned ntiny_n = m->noise > p->thres.noise; - unsigned ntiny_t = m->temp > p->thres.temp ; - - unsigned nlow_e = m->even > 2*p->thres.even ; - unsigned nlow_o = m->odd > 2*p->thres.odd ; - unsigned nlow_n = m->noise > 2*p->thres.noise; - unsigned nlow_t = m->temp > 2*p->thres.temp ; - - unsigned high_e = m->even > 4*p->thres.even ; - unsigned high_o = m->odd > 4*p->thres.odd ; - unsigned high_n = m->noise > 4*p->thres.noise; - unsigned high_t = m->temp > 4*p->thres.temp ; - - unsigned low_il = !n_big && !t_big && ntiny_n && ntiny_t; - unsigned high_il = !n_big && !t_big && nlow_n && nlow_t; - - if (low_il | high_il) { - s->interlaced_low += low_il; - s->interlaced_high += high_il; - } else { - s->tiny.even += ntiny_e; - s->tiny.odd += ntiny_o; - s->tiny.noise += ntiny_n; - s->tiny.temp += ntiny_t; - - s->low .even += nlow_e ; - s->low .odd += nlow_o ; - s->low .noise += nlow_n ; - s->low .temp += nlow_t ; - - s->high.even += high_e ; - s->high.odd += high_o ; - s->high.noise += high_n ; - s->high.temp += high_t ; - - if (m->even >= p->sad_thres) s->sad.even += m->even ; - if (m->odd >= p->sad_thres) s->sad.odd += m->odd ; - if (m->noise >= p->sad_thres) s->sad.noise += m->noise; - if (m->temp >= p->sad_thres) s->sad.temp += m->temp ; - } - s->num_blocks++; - s->max.even = MAX(s->max.even , m->even ); - s->max.odd = MAX(s->max.odd , m->odd ); - s->max.noise = MAX(s->max.noise, m->noise); - s->max.temp = MAX(s->max.temp , m->temp ); - - s->bigger.even += e_big ; - s->bigger.odd += o_big ; - s->bigger.noise += n_big ; - s->bigger.temp += t_big ; - - s->twox.even += e2x ; - s->twox.odd += o2x ; - s->twox.noise += n2x ; - s->twox.temp += t2x ; - -} - -static inline struct metrics -block_metrics_c(unsigned char *a, unsigned char *b, int as, int bs, - int lines, struct vf_priv_s *p, struct frame_stats *s) -{ - struct metrics tm; - tm.even = tm.odd = tm.noise = tm.temp = 0; - get_metrics_c(a, b, as, bs, lines, &tm); - if (sizeof(cmmx_t) < 8) - get_metrics_c(a+4, b+4, as, bs, lines, &tm); - get_block_stats(&tm, p, s); - return tm; -} - -static inline struct metrics -block_metrics_fast_c(unsigned char *a, unsigned char *b, int as, int bs, - int lines, struct vf_priv_s *p, struct frame_stats *s) -{ - struct metrics tm; - tm.even = tm.odd = tm.noise = tm.temp = 0; - get_metrics_fast_c(a, b, as, bs, lines, &tm); - if (sizeof(cmmx_t) < 8) - get_metrics_fast_c(a+4, b+4, as, bs, lines, &tm); - get_block_stats(&tm, p, s); - return tm; -} - -static inline struct metrics -block_metrics_faster_c(unsigned char *a, unsigned char *b, int as, int bs, - int lines, struct vf_priv_s *p, struct frame_stats *s) -{ - struct metrics tm; - tm.even = tm.odd = tm.noise = tm.temp = 0; - get_metrics_faster_c(a, b, as, bs, lines, &tm); - if (sizeof(cmmx_t) < 8) - get_metrics_faster_c(a+4, b+4, as, bs, lines, &tm); - get_block_stats(&tm, p, s); - return tm; -} - -#define MEQ(X,Y) ((X).even == (Y).even && (X).odd == (Y).odd && (X).temp == (Y).temp && (X).noise == (Y).noise) - -#define BLOCK_METRICS_TEMPLATE() \ - __asm__ volatile("pxor %mm7, %mm7\n\t" /* The result is colleted in mm7 */ \ - "pxor %mm6, %mm6\n\t" /* Temp to stay at 0 */ \ - ); \ - a -= as; \ - b -= bs; \ - do { \ - __asm__ volatile( \ - "movq (%0,%2), %%mm0\n\t" \ - "movq (%1,%3), %%mm1\n\t" /* mm1 = even */ \ - PSADBW(%%mm1, %%mm0, %%mm4, %%mm6) \ - "paddusw %%mm0, %%mm7\n\t" /* even diff */ \ - "movq (%0,%2,2), %%mm0\n\t" /* mm0 = old odd */ \ - "movq (%1,%3,2), %%mm2\n\t" /* mm2 = odd */ \ - "movq (%0), %%mm3\n\t" \ - "psubusb %4, %%mm3\n\t" \ - PAVGB(%%mm0, %%mm3) \ - PAVGB(%%mm0, %%mm3) /* mm3 = qup old odd */ \ - "movq %%mm0, %%mm5\n\t" \ - PSADBW(%%mm2, %%mm0, %%mm4, %%mm6) \ - "psllq $16, %%mm0\n\t" \ - "paddusw %%mm0, %%mm7\n\t" \ - "movq (%1), %%mm4\n\t" \ - "lea (%0,%2,2), %0\n\t" \ - "lea (%1,%3,2), %1\n\t" \ - "psubusb %4, %%mm4\n\t" \ - PAVGB(%%mm2, %%mm4) \ - PAVGB(%%mm2, %%mm4) /* mm4 = qup odd */ \ - PDIFFUBT(%%mm5, %%mm2, %%mm0) /* mm2 =abs(oldodd-odd) */ \ - "movq (%1,%3), %%mm5\n\t" \ - "psubusb %4, %%mm5\n\t" \ - PAVGB(%%mm1, %%mm5) \ - PAVGB(%%mm5, %%mm1) /* mm1 = qdown even */ \ - PAVGB((%1,%3), %%mm5) /* mm5 = qup next even */ \ - PDIFFUBT(%%mm1, %%mm3, %%mm0) /* mm3 = abs(qupoldo-qde) */ \ - PDIFFUBT(%%mm1, %%mm4, %%mm0) /* mm4 = abs(qupodd-qde) */ \ - PMINUBT(%%mm2, %%mm3, %%mm0) /* limit temp to odd diff */ \ - PMINUBT(%%mm2, %%mm4, %%mm0) /* limit noise to odd diff */ \ - "movq (%1,%3,2), %%mm2\n\t" \ - "psubusb %4, %%mm2\n\t" \ - PAVGB((%1), %%mm2) \ - PAVGB((%1), %%mm2) /* mm2 = qdown odd */ \ - "movq (%0,%2,2), %%mm1\n\t" \ - "psubusb %4, %%mm1\n\t" \ - PAVGB((%0), %%mm1) \ - PAVGB((%0), %%mm1) /* mm1 = qdown old odd */ \ - PDIFFUBT(%%mm5, %%mm2, %%mm0) /* mm2 = abs(qdo-qune) */ \ - PDIFFUBT(%%mm5, %%mm1, %%mm0) /* mm1 = abs(qdoo-qune) */ \ - PMINUBT(%%mm4, %%mm2, %%mm0) /* current */ \ - PMINUBT(%%mm3, %%mm1, %%mm0) /* old */ \ - PSUMBW(%%mm2, %%mm0, %%mm6) \ - PSUMBW(%%mm1, %%mm0, %%mm6) \ - "psllq $32, %%mm2\n\t" \ - "psllq $48, %%mm1\n\t" \ - "paddusw %%mm2, %%mm7\n\t" \ - "paddusw %%mm1, %%mm7\n\t" \ - : "=r" (a), "=r" (b) \ - : "r"((x86_reg)as), "r"((x86_reg)bs), "m" (ones), "0"(a), "1"(b), "X"(*a), "X"(*b) \ - ); \ - } while (--lines); - -#undef PSUMBW -#undef PSADBW -#undef PMAXUB -#undef PMINUBT -#undef PAVGB - -#define PSUMBW(X,T,Z) "psadbw " #Z "," #X "\n\t" -#define PSADBW(X,Y,T,Z) "psadbw " #X "," #Y "\n\t" -#define PMAXUB(X,Y) "pmaxub " #X "," #Y "\n\t" -#define PMINUBT(X,Y,T) "pminub " #X "," #Y "\n\t" -#define PAVGB(X,Y) "pavgb " #X "," #Y "\n\t" - -static inline struct metrics -block_metrics_mmx2(unsigned char *a, unsigned char *b, int as, int bs, - int lines, struct vf_priv_s *p, struct frame_stats *s) -{ - struct metrics tm; -#if !HAVE_MMX - mp_msg(MSGT_VFILTER, MSGL_FATAL, "block_metrics_mmx2: internal error\n"); -#else - static const unsigned long long ones = 0x0101010101010101ull; - x86_reg interlaced; - x86_reg prefetch_line = (((long)a>>3) & 7) + 10; -#ifdef DEBUG - struct frame_stats ts = *s; -#endif - __asm__ volatile("prefetcht0 (%0,%2)\n\t" - "prefetcht0 (%1,%3)\n\t" : - : "r" (a), "r" (b), - "r" (prefetch_line * as), "r" (prefetch_line * bs)); - - BLOCK_METRICS_TEMPLATE(); - - s->num_blocks++; - __asm__ volatile( - "movq %3, %%mm0\n\t" - "movq %%mm7, %%mm1\n\t" - "psubusw %%mm0, %%mm1\n\t" - "movq %%mm1, %%mm2\n\t" - "paddusw %%mm0, %%mm2\n\t" - "paddusw %%mm7, %%mm2\n\t" - "pshufw $0xb1, %%mm2, %%mm3\n\t" - "pavgw %%mm7, %%mm2\n\t" - "pshufw $0xb1, %%mm2, %%mm2\n\t" - "psubusw %%mm7, %%mm2\n\t" - "pcmpeqw %%mm6, %%mm2\n\t" /* 1 if >= 1.5x */ - "psubusw %%mm7, %%mm3\n\t" - "pcmpeqw %%mm6, %%mm3\n\t" /* 1 if >= 2x */ - "movq %1, %%mm4\n\t" - "movq %2, %%mm5\n\t" - "psubw %%mm2, %%mm4\n\t" - "psubw %%mm3, %%mm5\n\t" - "movq %%mm4, %1\n\t" - "movq %%mm5, %2\n\t" - "pxor %%mm4, %%mm4\n\t" - "pcmpeqw %%mm1, %%mm4\n\t" /* 1 if <= t */ - "psubusw %%mm0, %%mm1\n\t" - "pxor %%mm5, %%mm5\n\t" - "pcmpeqw %%mm1, %%mm5\n\t" /* 1 if <= 2t */ - "psubusw %%mm0, %%mm1\n\t" - "psubusw %%mm0, %%mm1\n\t" - "pcmpeqw %%mm6, %%mm1\n\t" /* 1 if <= 4t */ - "pshufw $0xb1, %%mm2, %%mm0\n\t" - "por %%mm2, %%mm0\n\t" /* 1 if not close */ - "punpckhdq %%mm0, %%mm0\n\t" - "movq %%mm4, %%mm2\n\t" /* tttt */ - "punpckhdq %%mm5, %%mm2\n\t" /* ttll */ - "por %%mm2, %%mm0\n\t" - "pcmpeqd %%mm6, %%mm0\n\t" /* close && big */ - "psrlq $16, %%mm0\n\t" - "psrlw $15, %%mm0\n\t" - "movd %%mm0, %0\n\t" - : "=r" (interlaced), "=m" (s->bigger), "=m" (s->twox) - : "m" (p->thres) - ); - - if (interlaced) { - s->interlaced_high += interlaced >> 16; - s->interlaced_low += interlaced; - } else { - __asm__ volatile( - "pcmpeqw %%mm0, %%mm0\n\t" /* -1 */ - "psubw %%mm0, %%mm4\n\t" - "psubw %%mm0, %%mm5\n\t" - "psubw %%mm0, %%mm1\n\t" - "paddw %0, %%mm4\n\t" - "paddw %1, %%mm5\n\t" - "paddw %2, %%mm1\n\t" - "movq %%mm4, %0\n\t" - "movq %%mm5, %1\n\t" - "movq %%mm1, %2\n\t" - : "=m" (s->tiny), "=m" (s->low), "=m" (s->high) - ); - - __asm__ volatile( - "pshufw $0, %2, %%mm0\n\t" - "psubusw %%mm7, %%mm0\n\t" - "pcmpeqw %%mm6, %%mm0\n\t" /* 0 if below sad_thres */ - "pand %%mm7, %%mm0\n\t" - "movq %%mm0, %%mm1\n\t" - "punpcklwd %%mm6, %%mm0\n\t" /* sad even, odd */ - "punpckhwd %%mm6, %%mm1\n\t" /* sad noise, temp */ - "paddd %0, %%mm0\n\t" - "paddd %1, %%mm1\n\t" - "movq %%mm0, %0\n\t" - "movq %%mm1, %1\n\t" - : "=m" (s->sad.even), "=m" (s->sad.noise) - : "m" (p->sad_thres) - ); - } - - __asm__ volatile( - "movq %%mm7, (%1)\n\t" - PMAXUW((%0), %%mm7) - "movq %%mm7, (%0)\n\t" - "emms" - : : "r" (&s->max), "r" (&tm), "X" (s->max) - : "memory" - ); -#ifdef DEBUG - if (1) { - struct metrics cm; - a -= 7*as; - b -= 7*bs; - cm = block_metrics_c(a, b, as, bs, 4, p, &ts); - if (!MEQ(tm, cm)) - mp_msg(MSGT_VFILTER, MSGL_WARN, "Bad metrics\n"); - if (s) { -# define CHECK(X) if (!MEQ(s->X, ts.X)) \ - mp_msg(MSGT_VFILTER, MSGL_WARN, "Bad " #X "\n"); - CHECK(tiny); - CHECK(low); - CHECK(high); - CHECK(sad); - CHECK(max); - } - } -#endif -#endif - return tm; -} - -static inline int -dint_copy_line_mmx2(unsigned char *dst, unsigned char *a, long bos, - long cos, int ds, int ss, int w, int t) -{ -#if !HAVE_MMX - mp_msg(MSGT_VFILTER, MSGL_FATAL, "dint_copy_line_mmx2: internal error\n"); - return 0; -#else - unsigned long len = (w+7) >> 3; - int ret; - __asm__ volatile ( - "pxor %%mm6, %%mm6 \n\t" /* deinterlaced pixel counter */ - "movd %0, %%mm7 \n\t" - "punpcklbw %%mm7, %%mm7 \n\t" - "punpcklwd %%mm7, %%mm7 \n\t" - "punpckldq %%mm7, %%mm7 \n\t" /* mm7 = threshold */ - : /* no output */ - : "rm" (t) - ); - do { - __asm__ volatile ( - "movq (%0), %%mm0\n\t" - "movq (%0,%3,2), %%mm1\n\t" - "movq %%mm0, (%2)\n\t" - "pmaxub %%mm1, %%mm0\n\t" - "pavgb (%0), %%mm1\n\t" - "psubusb %%mm1, %%mm0\n\t" - "paddusb %%mm7, %%mm0\n\t" /* mm0 = max-avg+thr */ - "movq (%0,%1), %%mm2\n\t" - "movq (%0,%5), %%mm3\n\t" - "movq %%mm2, %%mm4\n\t" - PDIFFUBT(%%mm1, %%mm2, %%mm5) - PDIFFUBT(%%mm1, %%mm3, %%mm5) - "pminub %%mm2, %%mm3\n\t" - "pcmpeqb %%mm3, %%mm2\n\t" /* b = min */ - "pand %%mm2, %%mm4\n\t" - "pandn (%0,%5), %%mm2\n\t" - "por %%mm4, %%mm2\n\t" - "pminub %%mm0, %%mm3\n\t" - "pcmpeqb %%mm0, %%mm3\n\t" /* set to 1s if >= threshold */ - "psubb %%mm3, %%mm6\n\t" /* count pixels above thr. */ - "pand %%mm3, %%mm1 \n\t" - "pandn %%mm2, %%mm3 \n\t" - "por %%mm3, %%mm1 \n\t" /* avg if >= threshold */ - "movq %%mm1, (%2,%4) \n\t" - : /* no output */ - : "r" (a), "r" ((x86_reg)bos), "r" ((x86_reg)dst), "r" ((x86_reg)ss), "r" ((x86_reg)ds), "r" ((x86_reg)cos) - ); - a += 8; - dst += 8; - } while (--len); - - __asm__ volatile ("pxor %%mm7, %%mm7 \n\t" - "psadbw %%mm6, %%mm7 \n\t" - "movd %%mm7, %0 \n\t" - "emms \n\t" - : "=r" (ret) - ); - return ret; -#endif -} - -static inline int -dint_copy_line(unsigned char *dst, unsigned char *a, long bos, - long cos, int ds, int ss, int w, int t) -{ - unsigned long len = ((unsigned long)w+sizeof(cmmx_t)-1) / sizeof(cmmx_t); - cmmx_t dint_count = 0; - cmmx_t thr; - t |= t << 8; - thr = t | (t << 16); - if (sizeof(cmmx_t) > 4) - thr |= thr << (sizeof(cmmx_t)*4); - do { - cmmx_t e = *(cmmx_t*)a; - cmmx_t ne = *(cmmx_t*)(a+2*ss); - cmmx_t o = *(cmmx_t*)(a+bos); - cmmx_t oo = *(cmmx_t*)(a+cos); - cmmx_t maxe = pmaxub(e, ne); - cmmx_t avge = pavgb(e, ne); - cmmx_t max_diff = maxe - avge + thr; /* 0<=max-avg<128, thr<128 */ - cmmx_t diffo = pdiffub(avge, o); - cmmx_t diffoo = pdiffub(avge, oo); - cmmx_t diffcmp = pcmpgtub(diffo, diffoo); - cmmx_t bo = ((oo ^ o) & diffcmp) ^ o; - cmmx_t diffbo = ((diffoo ^ diffo) & diffcmp) ^ diffo; - cmmx_t above_thr = ~pcmpgtub(max_diff, diffbo); - cmmx_t bo_or_avg = ((avge ^ bo) & above_thr) ^ bo; - dint_count += above_thr & ONE_BYTES; - *(cmmx_t*)(dst) = e; - *(cmmx_t*)(dst+ds) = bo_or_avg; - a += sizeof(cmmx_t); - dst += sizeof(cmmx_t); - } while (--len); - return psumbw(dint_count); -} - -static int -dint_copy_plane(unsigned char *d, unsigned char *a, unsigned char *b, - unsigned char *c, unsigned long w, unsigned long h, - unsigned long ds, unsigned long ss, unsigned long threshold, - long field, long mmx2) -{ - unsigned long ret = 0; - long bos = b - a; - long cos = c - a; - if (field) { - fast_memcpy(d, b, w); - h--; - d += ds; - a += ss; - } - bos += ss; - cos += ss; - while (h > 2) { - if (threshold >= 128) { - fast_memcpy(d, a, w); - fast_memcpy(d+ds, a+bos, w); - } else if (mmx2 == 1) { - ret += dint_copy_line_mmx2(d, a, bos, cos, ds, ss, w, threshold); - } else - ret += dint_copy_line(d, a, bos, cos, ds, ss, w, threshold); - h -= 2; - d += 2*ds; - a += 2*ss; - } - fast_memcpy(d, a, w); - if (h == 2) - fast_memcpy(d+ds, a+bos, w); - return ret; -} - -static void -copy_merge_fields(struct vf_priv_s *p, mp_image_t *dmpi, - unsigned char **old, unsigned char **new, unsigned long show) -{ - unsigned long threshold = 256; - unsigned long field = p->swapped; - unsigned long dint_pixels = 0; - unsigned char **other = old; - if (show >= 12 || !(show & 3)) - show >>= 2, other = new, new = old; - if (show <= 2) { /* Single field: de-interlace */ - threshold = p->dint_thres; - field ^= show & 1; - old = new; - } else if (show == 3) - old = new; - else - field ^= 1; - dint_pixels +=dint_copy_plane(dmpi->planes[0], old[0], new[0], - other[0], p->w, p->h, dmpi->stride[0], - p->stride, threshold, field, p->mmx2); - if (dmpi->flags & MP_IMGFLAG_PLANAR) { - if (p->luma_only) - old = new, other = new; - else - threshold = threshold/2 + 1; - field ^= p->chroma_swapped; - dint_copy_plane(dmpi->planes[1], old[1], new[1], - other[1], p->cw, p->ch, dmpi->stride[1], - p->chroma_stride, threshold, field, p->mmx2); - dint_copy_plane(dmpi->planes[2], old[2], new[2], - other[2], p->cw, p->ch, dmpi->stride[2], - p->chroma_stride, threshold, field, p->mmx2); - } - if (dint_pixels > 0 && p->verbose) - mp_msg(MSGT_VFILTER,MSGL_INFO,"Deinterlaced %lu pixels\n",dint_pixels); -} - -static void diff_planes(struct vf_priv_s *p, struct frame_stats *s, - unsigned char *of, unsigned char *nf, - int w, int h, int os, int ns, int swapped) -{ - int i, y; - int align = -(long)nf & 7; - of += align; - nf += align; - w -= align; - if (swapped) - of -= os, nf -= ns; - i = (h*3 >> 7) & ~1; - of += i*os + 8; - nf += i*ns + 8; - h -= i; - w -= 16; - - memset(s, 0, sizeof(*s)); - - for (y = (h-8) >> 3; y; y--) { - if (p->mmx2 == 1) { - for (i = 0; i < w; i += 8) - block_metrics_mmx2(of+i, nf+i, os, ns, 4, p, s); - } else if (p->fast > 3) { - for (i = 0; i < w; i += 8) - block_metrics_faster_c(of+i, nf+i, os, ns, 4, p, s); - } else if (p->fast > 1) { - for (i = 0; i < w; i += 8) - block_metrics_fast_c(of+i, nf+i, os, ns, 4, p, s); - } else { - for (i = 0; i < w; i += 8) - block_metrics_c(of+i, nf+i, os, ns, 4, p, s); - } - of += 8*os; - nf += 8*ns; - } -} - -#define METRICS(X) (X).even, (X).odd, (X).noise, (X).temp - -static void diff_fields(struct vf_priv_s *p, struct frame_stats *s, - unsigned char **old, unsigned char **new) -{ - diff_planes(p, s, old[0], new[0], p->w, p->h, - p->stride, p->stride, p->swapped); - s->sad.even = (s->sad.even * 16ul) / s->num_blocks; - s->sad.odd = (s->sad.odd * 16ul) / s->num_blocks; - s->sad.noise = (s->sad.noise * 16ul) / s->num_blocks; - s->sad.temp = (s->sad.temp * 16ul) / s->num_blocks; - if (p->verbose) - mp_msg(MSGT_VFILTER, MSGL_INFO, "%lu%c M:%d/%d/%d/%d - %d, " - "t:%d/%d/%d/%d, l:%d/%d/%d/%d, h:%d/%d/%d/%d, bg:%d/%d/%d/%d, " - "2x:%d/%d/%d/%d, sad:%d/%d/%d/%d, lil:%d, hil:%d, ios:%.1f\n", - p->inframes, p->chflag, METRICS(s->max), s->num_blocks, - METRICS(s->tiny), METRICS(s->low), METRICS(s->high), - METRICS(s->bigger), METRICS(s->twox), METRICS(s->sad), - s->interlaced_low, s->interlaced_high, - p->iosync / (double) p->in_inc); -} - -static const char *parse_args(struct vf_priv_s *p, const char *args) -{ - args--; - while (args && *++args && - (sscanf(args, "io=%lu:%lu", &p->out_dec, &p->in_inc) == 2 || - sscanf(args, "diff_thres=%hu", &p->thres.even ) == 1 || - sscanf(args, "comb_thres=%hu", &p->thres.noise) == 1 || - sscanf(args, "sad_thres=%lu", &p->sad_thres ) == 1 || - sscanf(args, "dint_thres=%lu", &p->dint_thres ) == 1 || - sscanf(args, "fast=%u", &p->fast ) == 1 || - sscanf(args, "mmx2=%lu", &p->mmx2 ) == 1 || - sscanf(args, "luma_only=%u", &p->luma_only ) == 1 || - sscanf(args, "verbose=%u", &p->verbose ) == 1 || - sscanf(args, "crop=%lu:%lu:%lu:%lu", &p->w, - &p->h, &p->crop_x, &p->crop_y) == 4)) - args = strchr(args, '/'); - return args; -} - -static unsigned long gcd(unsigned long x, unsigned long y) -{ - unsigned long t; - if (x > y) - t = x, x = y, y = t; - - while (x) { - t = y % x; - y = x; - x = t; - } - return y; -} - -static void init(struct vf_priv_s *p, mp_image_t *mpi) -{ - unsigned long i; - unsigned long plane_size, chroma_plane_size; - unsigned char *plane; - unsigned long cos, los; - p->crop_cx = p->crop_x >> mpi->chroma_x_shift; - p->crop_cy = p->crop_y >> mpi->chroma_y_shift; - if (mpi->flags & MP_IMGFLAG_ACCEPT_STRIDE) { - p->stride = (mpi->w + 15) & ~15; - p->chroma_stride = p->stride >> mpi->chroma_x_shift; - } else { - p->stride = mpi->width; - p->chroma_stride = mpi->chroma_width; - } - p->cw = p->w >> mpi->chroma_x_shift; - p->ch = p->h >> mpi->chroma_y_shift; - p->nplanes = 1; - p->static_idx = 0; - p->temp_idx = 0; - p->old_planes = p->planes[0]; - plane_size = mpi->h * p->stride; - chroma_plane_size = mpi->flags & MP_IMGFLAG_PLANAR ? - mpi->chroma_height * p->chroma_stride : 0; - p->memory_allocated = - malloc(NUM_STORED * (plane_size+2*chroma_plane_size) + - 8*p->chroma_stride + 4096); - /* align to page boundary */ - plane = p->memory_allocated + (-(long)p->memory_allocated & 4095); - memset(plane, 0, NUM_STORED * plane_size); - los = p->crop_x + p->crop_y * p->stride; - cos = p->crop_cx + p->crop_cy * p->chroma_stride; - for (i = 0; i != NUM_STORED; i++, plane += plane_size) { - p->planes[i][0] = plane; - p->planes[NUM_STORED + i][0] = plane + los; - } - if (mpi->flags & MP_IMGFLAG_PLANAR) { - p->nplanes = 3; - memset(plane, 0x80, NUM_STORED * 2 * chroma_plane_size); - for (i = 0; i != NUM_STORED; i++) { - p->planes[i][1] = plane; - p->planes[NUM_STORED + i][1] = plane + cos; - plane += chroma_plane_size; - p->planes[i][2] = plane; - p->planes[NUM_STORED + i][2] = plane + cos; - plane += chroma_plane_size; - } - } - p->out_dec <<= 2; - i = gcd(p->in_inc, p->out_dec); - p->in_inc /= i; - p->out_dec /= i; - p->iosync = 0; - p->num_fields = 3; -} - -static inline double get_time(void) -{ - struct timeval tv; - gettimeofday(&tv, 0); - return tv.tv_sec + tv.tv_usec * 1e-6; -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi) -{ - struct vf_priv_s *p = vf->priv; - static unsigned char **planes, planes_idx; - - if (mpi->type == MP_IMGTYPE_STATIC) return; - - if (!p->planes[0][0]) init(p, mpi); - - if (mpi->type == MP_IMGTYPE_TEMP || - (mpi->type == MP_IMGTYPE_IPB && !(mpi->flags & MP_IMGFLAG_READABLE))) - planes_idx = NUM_STORED/2 + (++p->temp_idx % (NUM_STORED/2)); - else - planes_idx = ++p->static_idx % (NUM_STORED/2); - planes = p->planes[planes_idx]; - mpi->priv = p->planes[NUM_STORED + planes_idx]; - if (mpi->priv == p->old_planes) { - unsigned char **old_planes = - p->planes[NUM_STORED + 2 + (++p->temp_idx & 1)]; - my_memcpy_pic(old_planes[0], p->old_planes[0], - p->w, p->h, p->stride, p->stride); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(old_planes[1], p->old_planes[1], - p->cw, p->ch, p->chroma_stride, p->chroma_stride); - my_memcpy_pic(old_planes[2], p->old_planes[2], - p->cw, p->ch, p->chroma_stride, p->chroma_stride); - } - p->old_planes = old_planes; - p->num_copies++; - } - mpi->planes[0] = planes[0]; - mpi->stride[0] = p->stride; - if (mpi->flags & MP_IMGFLAG_PLANAR) { - mpi->planes[1] = planes[1]; - mpi->planes[2] = planes[2]; - mpi->stride[1] = mpi->stride[2] = p->chroma_stride; - } - mpi->width = p->stride; - - mpi->flags |= MP_IMGFLAG_DIRECT; - mpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK; -} - -static inline long -cmpe(unsigned long x, unsigned long y, unsigned long err, unsigned long e) -{ - long diff = x-y; - long unit = ((x+y+err) >> e); - long ret = (diff > unit) - (diff < -unit); - unit >>= 1; - return ret + (diff > unit) - (diff < -unit); -} - -static unsigned long -find_breaks(struct vf_priv_s *p, struct frame_stats *s) -{ - struct frame_stats *ps = &p->stats[(p->inframes-1) & 1]; - long notfilm = 5*p->in_inc - p->out_dec; - unsigned long n = s->num_blocks >> 8; - unsigned long sad_comb_cmp = cmpe(s->sad.temp, s->sad.noise, 512, 1); - unsigned long ret = 8; - - if (cmpe(s->sad.temp, s->sad.even, 512, 1) > 0) - mp_msg(MSGT_VFILTER, MSGL_WARN, - "@@@@@@@@ Bottom-first field??? @@@@@@@@\n"); - if (s->sad.temp > 1000 && s->sad.noise > 1000) - return 3; - if (s->interlaced_high >= 2*n && s->sad.temp > 256 && s->sad.noise > 256) - return 3; - if (s->high.noise > s->num_blocks/4 && s->sad.noise > 10000 && - s->sad.noise > 2*s->sad.even && s->sad.noise > 2*ps->sad.odd) { - // Mid-frame scene change - if (s->tiny.temp + s->interlaced_low < n || - s->low.temp + s->interlaced_high < n/4 || - s->high.temp + s->interlaced_high < n/8 || - s->sad.temp < 160) - return 1; - return 3; - } - if (s->high.temp > s->num_blocks/4 && s->sad.temp > 10000 && - s->sad.temp > 2*ps->sad.odd && s->sad.temp > 2*ps->sad.even) { - // Start frame scene change - if (s->tiny.noise + s->interlaced_low < n || - s->low.noise + s->interlaced_high < n/4 || - s->high.noise + s->interlaced_high < n/8 || - s->sad.noise < 160) - return 2; - return 3; - } - if (sad_comb_cmp == 2) - return 2; - if (sad_comb_cmp == -2) - return 1; - - if (s->tiny.odd > 3*MAX(n,s->tiny.even) + s->interlaced_low) - return 1; - if (s->tiny.even > 3*MAX(n,s->tiny.odd)+s->interlaced_low && - (!sad_comb_cmp || (s->low.noise <= n/4 && s->low.temp <= n/4))) - return 4; - - if (s->sad.noise < 64 && s->sad.temp < 64 && - s->low.noise <= n/2 && s->high.noise <= n/4 && - s->low.temp <= n/2 && s->high.temp <= n/4) - goto still; - - if (s->tiny.temp > 3*MAX(n,s->tiny.noise) + s->interlaced_low) - return 2; - if (s->tiny.noise > 3*MAX(n,s->tiny.temp) + s->interlaced_low) - return 1; - - if (s->low.odd > 3*MAX(n/4,s->low.even) + s->interlaced_high) - return 1; - if (s->low.even > 3*MAX(n/4,s->low.odd)+s->interlaced_high && - s->sad.even > 2*s->sad.odd && - (!sad_comb_cmp || (s->low.noise <= n/4 && s->low.temp <= n/4))) - return 4; - - if (s->low.temp > 3*MAX(n/4,s->low.noise) + s->interlaced_high) - return 2; - if (s->low.noise > 3*MAX(n/4,s->low.temp) + s->interlaced_high) - return 1; - - if (sad_comb_cmp == 1 && s->sad.noise < 64) - return 2; - if (sad_comb_cmp == -1 && s->sad.temp < 64) - return 1; - - if (s->tiny.odd <= n || (s->tiny.noise <= n/2 && s->tiny.temp <= n/2)) { - if (s->interlaced_low <= n) { - if (p->num_fields == 1) - goto still; - if (s->tiny.even <= n || ps->tiny.noise <= n/2) - /* Still frame */ - goto still; - if (s->bigger.even >= 2*MAX(n,s->bigger.odd) + s->interlaced_low) - return 4; - if (s->low.even >= 2*n + s->interlaced_low) - return 4; - goto still; - } - } - if (s->low.odd <= n/4) { - if (s->interlaced_high <= n/4) { - if (p->num_fields == 1) - goto still; - if (s->low.even <= n/4) - /* Still frame */ - goto still; - if (s->bigger.even >= 2*MAX(n/4,s->bigger.odd)+s->interlaced_high) - return 4; - if (s->low.even >= n/2 + s->interlaced_high) - return 4; - goto still; - } - } - if (s->bigger.temp > 2*MAX(n,s->bigger.noise) + s->interlaced_low) - return 2; - if (s->bigger.noise > 2*MAX(n,s->bigger.temp) + s->interlaced_low) - return 1; - if (s->bigger.temp > 2*MAX(n,s->bigger.noise) + s->interlaced_high) - return 2; - if (s->bigger.noise > 2*MAX(n,s->bigger.temp) + s->interlaced_high) - return 1; - if (s->twox.temp > 2*MAX(n,s->twox.noise) + s->interlaced_high) - return 2; - if (s->twox.noise > 2*MAX(n,s->twox.temp) + s->interlaced_high) - return 1; - if (s->bigger.even > 2*MAX(n,s->bigger.odd) + s->interlaced_low && - s->bigger.temp < n && s->bigger.noise < n) - return 4; - if (s->interlaced_low > MIN(2*n, s->tiny.odd)) - return 3; - ret = 8 + (1 << (s->sad.temp > s->sad.noise)); - still: - if (p->num_fields == 1 && p->prev_fields == 3 && notfilm >= 0 && - (s->tiny.temp <= s->tiny.noise || s->sad.temp < s->sad.noise+16)) - return 1; - if (p->notout < p->num_fields && p->iosync > 2*p->in_inc && notfilm < 0) - notfilm = 0; - if (p->num_fields < 2 || - (p->num_fields == 2 && p->prev_fields == 2 && notfilm < 0)) - return ret; - if (!notfilm && (p->prev_fields&~1) == 2) { - if (p->prev_fields + p->num_fields == 5) { - if (s->tiny.noise <= s->tiny.temp || - s->low.noise == 0 || s->low.noise < s->low.temp || - s->sad.noise < s->sad.temp+16) - return 2; - } - if (p->prev_fields + p->num_fields == 4) { - if (s->tiny.temp <= s->tiny.noise || - s->low.temp == 0 || s->low.temp < s->low.noise || - s->sad.temp < s->sad.noise+16) - return 1; - } - } - if (p->num_fields > 2 && - ps->sad.noise > s->sad.noise && ps->sad.noise > s->sad.temp) - return 4; - return 2 >> (s->sad.noise > s->sad.temp); -} - -#define ITOC(X) (!(X) ? ' ' : (X) + ((X)>9 ? 'a'-10 : '0')) - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi = NULL; - struct vf_priv_s *p = vf->priv; - unsigned char **planes, **old_planes; - struct frame_stats *s = &p->stats[p->inframes & 1]; - struct frame_stats *ps = &p->stats[(p->inframes-1) & 1]; - int swapped = 0; - const int flags = mpi->fields; - int breaks, prev; - int show_fields = 0; - int dropped_fields = 0; - double start_time, diff_time; - char prev_chflag = p->chflag; - int keep_rate; - - if (!p->planes[0][0]) init(p, mpi); - - old_planes = p->old_planes; - - if ((mpi->flags & MP_IMGFLAG_DIRECT) && mpi->priv) { - planes = mpi->priv; - mpi->priv = 0; - } else { - planes = p->planes[2 + (++p->temp_idx & 1)]; - my_memcpy_pic(planes[0], - mpi->planes[0] + p->crop_x + p->crop_y * mpi->stride[0], - p->w, p->h, p->stride, mpi->stride[0]); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(planes[1], - mpi->planes[1] + p->crop_cx + p->crop_cy * mpi->stride[1], - p->cw, p->ch, p->chroma_stride, mpi->stride[1]); - my_memcpy_pic(planes[2], - mpi->planes[2] + p->crop_cx + p->crop_cy * mpi->stride[2], - p->cw, p->ch, p->chroma_stride, mpi->stride[2]); - p->num_copies++; - } - } - - p->old_planes = planes; - p->chflag = ';'; - if (flags & MP_IMGFIELD_ORDERED) { - swapped = !(flags & MP_IMGFIELD_TOP_FIRST); - p->chflag = (flags & MP_IMGFIELD_REPEAT_FIRST ? '|' : - flags & MP_IMGFIELD_TOP_FIRST ? ':' : '.'); - } - p->swapped = swapped; - - start_time = get_time(); - if (p->chflag == '|') { - *s = ppzs; - p->iosync += p->in_inc; - } else if ((p->fast & 1) && prev_chflag == '|') - *s = pprs; - else - diff_fields(p, s, old_planes, planes); - diff_time = get_time(); - p->diff_time += diff_time - start_time; - breaks = p->inframes ? find_breaks(p, s) : 2; - p->inframes++; - keep_rate = 4*p->in_inc == p->out_dec; - - switch (breaks) { - case 0: - case 8: - case 9: - case 10: - if (!keep_rate && p->notout < p->num_fields && p->iosync < 2*p->in_inc) - break; - if (p->notout < p->num_fields) - dropped_fields = -2; - case 4: - if (keep_rate || p->iosync >= -2*p->in_inc) - show_fields = (4<num_fields)-1; - break; - case 3: - if (keep_rate) - show_fields = 2; - else if (p->iosync > 0) { - if (p->notout >= p->num_fields && p->iosync > 2*p->in_inc) { - show_fields = 4; /* prev odd only */ - if (p->num_fields > 1) - show_fields |= 8; /* + prev even */ - } else { - show_fields = 2; /* even only */ - if (p->notout >= p->num_fields) - dropped_fields += p->num_fields; - } - } - break; - case 2: - if (p->iosync <= -3*p->in_inc) { - if (p->notout >= p->num_fields) - dropped_fields = p->num_fields; - break; - } - if (p->num_fields == 1) { - int prevbreak = ps->sad.noise >= 128; - if (p->iosync < 4*p->in_inc) { - show_fields = 3; - dropped_fields = prevbreak; - } else { - show_fields = 4 | (!prevbreak << 3); - if (p->notout < 1 + p->prev_fields) - dropped_fields = -!prevbreak; - } - break; - } - default: - if (keep_rate) - show_fields = 3 << (breaks & 1); - else if (p->notout >= p->num_fields && - p->iosync >= (breaks == 1 ? -p->in_inc : - p->in_inc << (p->num_fields == 1))) { - show_fields = (1 << (2 + p->num_fields)) - (1<notout >= p->num_fields) - dropped_fields += p->num_fields + 2 - breaks; - if (breaks == 1) { - if (p->iosync >= 4*p->in_inc) - show_fields = 6; - } else if (p->iosync > -3*p->in_inc) - show_fields = 3; /* odd+even */ - } - break; - } - - show_fields &= 15; - prev = p->prev_fields; - if (breaks < 8) { - if (p->num_fields == 1) - breaks &= ~4; - if (breaks) - p->num_breaks++; - if (breaks == 3) - p->prev_fields = p->num_fields = 1; - else if (breaks) { - p->prev_fields = p->num_fields + (breaks==1) - (breaks==4); - p->num_fields = breaks - (breaks == 4) + (p->chflag == '|'); - } else - p->num_fields += 2; - } else - p->num_fields += 2; - - p->iosync += 4 * p->in_inc; - if (p->chflag == '|') - p->iosync += p->in_inc; - - if (show_fields) { - p->iosync -= p->out_dec; - p->notout = !(show_fields & 1) + !(show_fields & 3); - if (((show_fields & 3) == 3 && - (s->low.noise + s->interlaced_low < (s->num_blocks>>8) || - s->sad.noise < 160)) || - ((show_fields & 12) == 12 && - (ps->low.noise + ps->interlaced_low < (s->num_blocks>>8) || - ps->sad.noise < 160))) { - p->export_count++; - dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT, - MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE, - p->w, p->h); - if ((show_fields & 3) != 3) planes = old_planes; - dmpi->planes[0] = planes[0]; - dmpi->stride[0] = p->stride; - dmpi->width = mpi->width; - if (mpi->flags & MP_IMGFLAG_PLANAR) { - dmpi->planes[1] = planes[1]; - dmpi->planes[2] = planes[2]; - dmpi->stride[1] = p->chroma_stride; - dmpi->stride[2] = p->chroma_stride; - } - } else { - p->merge_count++; - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - p->w, p->h); - copy_merge_fields(p, dmpi, old_planes, planes, show_fields); - } - p->outframes++; - } else - p->notout += 2; - - if (p->verbose) - mp_msg(MSGT_VFILTER, MSGL_INFO, "%lu %lu: %x %c %c %lu%s%s%c%s\n", - p->inframes, p->outframes, - breaks, breaks<8 && breaks>0 ? (int) p->prev_fields+'0' : ' ', - ITOC(show_fields), - p->num_breaks, 5*p->in_inc == p->out_dec && breaks<8 && - breaks>0 && ((prev&~1)!=2 || prev+p->prev_fields!=5) ? - " ######## bad telecine ########" : "", - dropped_fields ? " ======== dropped ":"", ITOC(dropped_fields), - !show_fields || (show_fields & (show_fields-1)) ? - "" : " @@@@@@@@@@@@@@@@@"); - - p->merge_time += get_time() - diff_time; - pts = vf_detc_adjust_pts(&p->ptsbuf, pts, 0, !show_fields); - return show_fields ? vf_next_put_image(vf, dmpi, pts) : 0; -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - /* FIXME - support more formats */ - switch (fmt) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - case IMGFMT_411P: - case IMGFMT_422P: - case IMGFMT_444P: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - struct MPOpts *opts = vf->opts; - unsigned long cxm = 0; - unsigned long cym = 0; - struct vf_priv_s *p = vf->priv; - vf_detc_init_pts_buf(&p->ptsbuf); - // rounding: - if(!IMGFMT_IS_RGB(outfmt) && !IMGFMT_IS_BGR(outfmt)){ - switch(outfmt){ - case IMGFMT_444P: - case IMGFMT_Y800: - case IMGFMT_Y8: - break; - case IMGFMT_YVU9: - case IMGFMT_IF09: - cym = 3; - case IMGFMT_411P: - cxm = 3; - break; - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - cym = 1; - default: - cxm = 1; - } - } - p->chroma_swapped = !!(p->crop_y & (cym+1)); - if (p->w) p->w += p->crop_x & cxm; - if (p->h) p->h += p->crop_y & cym; - p->crop_x &= ~cxm; - p->crop_y &= ~cym; - if (!p->w || p->w > width ) p->w = width; - if (!p->h || p->h > height) p->h = height; - if (p->crop_x + p->w > width ) p->crop_x = 0; - if (p->crop_y + p->h > height) p->crop_y = 0; - - if(!opts->screen_size_x && !opts->screen_size_y){ - d_width = d_width * p->w/width; - d_height = d_height * p->h/height; - } - return vf_next_config(vf, p->w, p->h, d_width, d_height, flags, outfmt); -} - -static void uninit(struct vf_instance *vf) -{ - struct vf_priv_s *p = vf->priv; - mp_msg(MSGT_VFILTER, MSGL_INFO, "diff_time: %.3f, merge_time: %.3f, " - "export: %lu, merge: %lu, copy: %lu\n", p->diff_time, p->merge_time, - p->export_count, p->merge_count, p->num_copies); - free(p->memory_allocated); - free(p); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - struct vf_priv_s *p; - vf->get_image = get_image; - vf->put_image = put_image; - vf->config = config; - vf->query_format = query_format; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); - p->out_dec = 5; - p->in_inc = 4; - p->thres.noise = 128; - p->thres.even = 128; - p->sad_thres = 64; - p->dint_thres = 4; - p->luma_only = 0; - p->fast = 3; - p->mmx2 = gCpuCaps.hasMMX2; - if (args) { - const char *args_remain = parse_args(p, args); - if (args_remain) { - mp_msg(MSGT_VFILTER, MSGL_FATAL, - "filmdint: unknown suboption: %s\n", args_remain); - return 0; - } - if (p->out_dec < p->in_inc) { - mp_msg(MSGT_VFILTER, MSGL_FATAL, - "filmdint: increasing the frame rate is not supported\n"); - return 0; - } - } - if (p->mmx2 > 2) - p->mmx2 = 0; -#if !HAVE_MMX - p->mmx2 = 0; -#endif - p->thres.odd = p->thres.even; - p->thres.temp = p->thres.noise; - p->diff_time = 0; - p->merge_time = 0; - return 1; -} - -const vf_info_t vf_info_filmdint = { - "Advanced inverse telecine filer", - "filmdint", - "Zoltan Hidvegi", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_fixpts.c b/libmpcodecs/vf_fixpts.c deleted file mode 100644 index 507c41c660..0000000000 --- a/libmpcodecs/vf_fixpts.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - double current; - double step; - int autostart; - int autostep; - unsigned have_step:1; - unsigned print:1; -}; - -static int put_image(vf_instance_t *vf, mp_image_t *src, double pts) -{ - struct vf_priv_s *p = vf->priv; - - if (p->print) { - if (pts == MP_NOPTS_VALUE) - mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: undef\n"); - else - mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: %f\n", pts); - } - if (pts != MP_NOPTS_VALUE && p->autostart != 0) { - p->current = pts; - if (p->autostart > 0) - p->autostart--; - } else if (pts != MP_NOPTS_VALUE && p->autostep > 0) { - p->step = pts - p->current; - p->current = pts; - p->autostep--; - p->have_step = 1; - } else if (p->have_step) { - p->current += p->step; - pts = p->current; - } else { - pts = MP_NOPTS_VALUE; - } - return vf_next_put_image(vf, src, pts); -} - -static void uninit(vf_instance_t *vf) -{ - free(vf->priv); -} - -static int parse_args(struct vf_priv_s *p, const char *args) -{ - int pos; - double num, denom = 1; - int iarg; - - while (*args != 0) { - pos = 0; - if (sscanf(args, "print%n", &pos) == 0 && pos > 0) { - p->print = 1; - } else if (sscanf(args, "fps=%lf%n/%lf%n", &num, &pos, &denom, &pos) >= - 1 && pos > 0) { - p->step = denom / num; - p->have_step = 1; - } else if (sscanf(args, "start=%lf%n", &num, &pos) >= 1 && pos > 0) { - p->current = num; - } else if (sscanf(args, "autostart=%d%n", &iarg, &pos) == 1 && pos > 0) { - p->autostart = iarg; - } else if (sscanf(args, "autofps=%d%n", &iarg, &pos) == 1 && pos > 0) { - p->autostep = iarg; - } else { - mp_msg(MSGT_VFILTER, MSGL_FATAL, - "fixpts: unknown suboption: %s\n", args); - return 0; - } - args += pos; - if (*args == ':') - args++; - } - return 1; -} - -static int open(vf_instance_t *vf, char *args) -{ - struct vf_priv_s *p; - struct vf_priv_s ptmp = { - .current = 0, - .step = 0, - .autostart = 0, - .autostep = 0, - .have_step = 0, - .print = 0, - }; - - if (!parse_args(&ptmp, args == NULL ? "" : args)) - return 0; - - vf->put_image = put_image; - vf->uninit = uninit; - vf->priv = p = malloc(sizeof(struct vf_priv_s)); - *p = ptmp; - p->current = -p->step; - - return 1; -} - -const vf_info_t vf_info_fixpts = { - "Fix presentation timestamps", - "fixpts", - "Nicolas George", - "", - &open, - NULL -}; diff --git a/libmpcodecs/vf_framestep.c b/libmpcodecs/vf_framestep.c deleted file mode 100644 index d6aad9a90a..0000000000 --- a/libmpcodecs/vf_framestep.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * filter to ouput only 1 every n frame, or only the I (key)frame - * - * The parameters are: - * - * [I] | [i]num - * - * if you call the filter with I (uppercase) as the parameter - * ... -vf framestep=I ... - * then ONLY the keyframes are outputted. - * For DVD it means, generally, one every 15 frames (IBBPBBPBBPBBPBB), for avi it means - * every scene change or every keyint value (see -lavcopts). - * - * if you call the filter with the i (lowercase) - * ... -vf framestep=i ... - * then a I! followed by a cr is printed when a key frame (eg Intra frame) is - * found, leaving the current line of mplayer, where you got the time, in - * seconds, and frame of the key. Use this information to split the AVI. - * - * After the i or alone you can put a positive number and only one frame every - * x (the number you set) is passed on the filter chain, limiting the output - * of the frame. - * - * Example - * ... -vf framestep=i20 ... - * Dump one every 20 frames, printing on the console when a I-Frame is encounter. - * - * ... -vf framestep=25 - * Dump one every 25 frames. - * - * If you call the filter without parameter it does nothing (except using memory - * and resource of your system,. of course). - * - * This filter doesn' t work like the option -sstep seconds. - * - * The -sstep seek to the new position, without decoding all frames but, - * expecially on avi file coded whith mpeg4 (lavc or xvid or divx), the - * seek is not always too much precise. - * - * This filter simply discard the unwanted frames, so you are very precise in - * counting the frame but sometime you use a lot of CPU for nothing. - * - * As usual it depends on what you're doing. - * - * copyright (c) 2003 Daniele Forghieri ( guru@digitalfantasy.it ) - * - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -/* Uncomment if you want to print some info on the format */ -// #define DUMP_FORMAT_DATA - -/* Private data */ -struct vf_priv_s { - /* Current frame */ - int frame_cur; - /* Frame output step, 0 = all */ - int frame_step; - /* Only I-Frame (2), print on I-Frame (1) */ - int dump_iframe; -}; - -/* Filter handler */ -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - struct vf_priv_s *priv; - int skip; - - priv = vf->priv; - - /* Print the 'I' if is a intra frame. The \n advance the current line so you got the - * current file time (in second) and the frame number on the console ;-) - */ - if (priv->dump_iframe) { - if (mpi->pict_type == 1) { - mp_msg(MSGT_VFILTER, MSGL_INFO, "I!\n"); - } - } - - /* decide if frame must be shown */ - if (priv->dump_iframe == 2) { - /* Only key frame */ - skip = mpi->pict_type == 1 ? 0 : 1; - } - else { - /* Only 1 every frame_step */ - skip = 0; - if ((priv->frame_step != 0) && ((priv->frame_cur % priv->frame_step) != 0)) { - skip = 1; - } - } - /* Increment current frame */ - ++priv->frame_cur; - - if (skip == 0) { - /* Get image, export type (we don't modify tghe image) */ - dmpi=vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_EXPORT, 0, - mpi->w, mpi->h); - /* Copy only the pointer ( MP_IMGTYPE_EXPORT ! ) */ - dmpi->planes[0] = mpi->planes[0]; - dmpi->planes[1] = mpi->planes[1]; - dmpi->planes[2] = mpi->planes[2]; - - dmpi->stride[0] = mpi->stride[0]; - dmpi->stride[1] = mpi->stride[1]; - dmpi->stride[2] = mpi->stride[2]; - - dmpi->width = mpi->width; - dmpi->height = mpi->height; - - /* Chain to next filter / output ... */ - return vf_next_put_image(vf, dmpi, pts); - } - - /* Skip the frame */ - return 0; -} - -static void uninit(struct vf_instance *vf) -{ - /* Free private data */ - free(vf->priv); -} - -/* Main entry funct for the filter */ -static int vf_open(vf_instance_t *vf, char *args) -{ - struct vf_priv_s *p; - - vf->put_image = put_image; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); - if (p == NULL) { - return 0; - } - - if (args != NULL) { -#ifdef DUMP_FORMAT_DATA - if (*args == 'd') { - p->dump_iframe = 3; - } - else -#endif - if (*args == 'I') { - /* Dump only KEY (ie INTRA) frame */ - p->dump_iframe = 2; - } - else { - if (*args == 'i') { - /* Print a 'I!' when a i-frame is encounter */ - p->dump_iframe = 1; - ++args; - } - - if (*args != '\0') { - p->frame_step = atoi(args); - if (p->frame_step <= 0) { - mp_tmsg(MSGT_VFILTER, MSGL_WARN, "[VF_FRAMESTEP] Error parsing argument.\n"); - return 0; - } - } - } - } - return 1; -} - -const vf_info_t vf_info_framestep = { - "Dump one every n / key frames", - "framestep", - "Daniele Forghieri", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_fspp.c b/libmpcodecs/vf_fspp.c deleted file mode 100644 index 59d731c529..0000000000 --- a/libmpcodecs/vf_fspp.c +++ /dev/null @@ -1,2112 +0,0 @@ -/* - * Copyright (C) 2003 Michael Niedermayer - * Copyright (C) 2005 Nikolaj Poroshin - * - * This file is part of MPlayer. - * - * 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. - */ - -/* - * This implementation is based on an algorithm described in - * "Aria Nosratinia Embedded Post-Processing for - * Enhancement of Compressed Images (1999)" - * (http://citeseer.nj.nec.com/nosratinia99embedded.html) - * Futher, with splitting (i)dct into hor/ver passes, one of them can be - * performed once per block, not pixel. This allows for much better speed. - */ - -/* - Heavily optimized version of SPP filter by Nikolaj - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "config.h" - -#include "mp_msg.h" -#include "cpudetect.h" -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libvo/fastmemcpy.h" -#include "mangle.h" - -typedef short DCTELEM; - -//===========================================================================// -#define BLOCKSZ 12 - -static const short custom_threshold[64]= -// values (296) can't be too high -// -it causes too big quant dependence -// or maybe overflow(check), which results in some flashing -{ 71, 296, 295, 237, 71, 40, 38, 19, - 245, 193, 185, 121, 102, 73, 53, 27, - 158, 129, 141, 107, 97, 73, 50, 26, - 102, 116, 109, 98, 82, 66, 45, 23, - 71, 94, 95, 81, 70, 56, 38, 20, - 56, 77, 74, 66, 56, 44, 30, 15, - 38, 53, 50, 45, 38, 30, 21, 11, - 20, 27, 26, 23, 20, 15, 11, 5 -}; - -static const uint8_t __attribute__((aligned(32))) dither[8][8]={ - { 0, 48, 12, 60, 3, 51, 15, 63, }, - { 32, 16, 44, 28, 35, 19, 47, 31, }, - { 8, 56, 4, 52, 11, 59, 7, 55, }, - { 40, 24, 36, 20, 43, 27, 39, 23, }, - { 2, 50, 14, 62, 1, 49, 13, 61, }, - { 34, 18, 46, 30, 33, 17, 45, 29, }, - { 10, 58, 6, 54, 9, 57, 5, 53, }, - { 42, 26, 38, 22, 41, 25, 37, 21, }, -}; - -struct vf_priv_s { //align 16 ! - uint64_t threshold_mtx_noq[8*2]; - uint64_t threshold_mtx[8*2];//used in both C & MMX (& later SSE2) versions - - int log2_count; - int temp_stride; - int qp; - int mpeg2; - int prev_q; - uint8_t *src; - int16_t *temp; - int bframes; - char *non_b_qp; -}; - - -#if !HAVE_MMX - -//This func reads from 1 slice, 1 and clears 0 & 1 -static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale) -{int y, x; -#define STORE(pos) \ - temp= (src[x + pos] + (d[pos]>>log2_scale))>>(6-log2_scale); \ - src[x + pos]=src[x + pos - 8*src_stride]=0; \ - if(temp & 0x100) temp= ~(temp>>31); \ - dst[x + pos]= temp; - - for(y=0; y>log2_scale))>>(6-log2_scale); \ - src[x + pos + 16*src_stride]=0; \ - if(temp & 0x100) temp= ~(temp>>31); \ - dst[x + pos]= temp; - - for(y=0; ythreshold_mtx)[a]=q * ((short*)p->threshold_mtx_noq)[a];//ints faster in C -} - -static void column_fidct_c(int16_t* thr_adr, DCTELEM *data, DCTELEM *output, int cnt); -static void row_idct_c(DCTELEM* workspace, - int16_t* output_adr, int output_stride, int cnt); -static void row_fdct_c(DCTELEM *data, const uint8_t *pixels, int line_size, int cnt); - -//this is rather ugly, but there is no need for function pointers -#define store_slice_s store_slice_c -#define store_slice2_s store_slice2_c -#define mul_thrmat_s mul_thrmat_c -#define column_fidct_s column_fidct_c -#define row_idct_s row_idct_c -#define row_fdct_s row_fdct_c - -#else /* HAVE_MMX */ - -//This func reads from 1 slice, 1 and clears 0 & 1 -static void store_slice_mmx(uint8_t *dst, int16_t *src, long dst_stride, long src_stride, long width, long height, long log2_scale) -{ - const uint8_t *od=&dither[0][0]; - const uint8_t *end=&dither[height][0]; - width = (width+7)&~7; - dst_stride-=width; - //src_stride=(src_stride-width)*2; - __asm__ volatile( - "mov %5, %%"REG_d" \n\t" - "mov %6, %%"REG_S" \n\t" - "mov %7, %%"REG_D" \n\t" - "mov %1, %%"REG_a" \n\t" - "movd %%"REG_d", %%mm5 \n\t" - "xor $-1, %%"REG_d" \n\t" - "mov %%"REG_a", %%"REG_c" \n\t" - "add $7, %%"REG_d" \n\t" - "neg %%"REG_a" \n\t" - "sub %0, %%"REG_c" \n\t" - "add %%"REG_c", %%"REG_c" \n\t" - "movd %%"REG_d", %%mm2 \n\t" - "mov %%"REG_c", %1 \n\t" - "mov %2, %%"REG_d" \n\t" - "shl $4, %%"REG_a" \n\t" - - "2: \n\t" - "movq (%%"REG_d"), %%mm3 \n\t" - "movq %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - "punpcklbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm4 \n\t" - "mov %0, %%"REG_c" \n\t" - "psraw %%mm5, %%mm3 \n\t" - "psraw %%mm5, %%mm4 \n\t" - "1: \n\t" - "movq %%mm7, (%%"REG_S",%%"REG_a",) \n\t" - "movq (%%"REG_S"), %%mm0 \n\t" - "movq 8(%%"REG_S"), %%mm1 \n\t" - - "movq %%mm7, 8(%%"REG_S",%%"REG_a",) \n\t" - "paddw %%mm3, %%mm0 \n\t" - "paddw %%mm4, %%mm1 \n\t" - - "movq %%mm7, (%%"REG_S") \n\t" - "psraw %%mm2, %%mm0 \n\t" - "psraw %%mm2, %%mm1 \n\t" - - "movq %%mm7, 8(%%"REG_S") \n\t" - "packuswb %%mm1, %%mm0 \n\t" - "add $16, %%"REG_S" \n\t" - - "movq %%mm0, (%%"REG_D") \n\t" - "add $8, %%"REG_D" \n\t" - "sub $8, %%"REG_c" \n\t" - "jg 1b \n\t" - "add %1, %%"REG_S" \n\t" - "add $8, %%"REG_d" \n\t" - "add %3, %%"REG_D" \n\t" - "cmp %4, %%"REG_d" \n\t" - "jl 2b \n\t" - - : - : "m" (width), "m" (src_stride), "erm" (od), "m" (dst_stride), "erm" (end), - "m" (log2_scale), "m" (src), "m" (dst) //input - : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D - ); -} - -//This func reads from 2 slices, 0 & 2 and clears 2-nd -static void store_slice2_mmx(uint8_t *dst, int16_t *src, long dst_stride, long src_stride, long width, long height, long log2_scale) -{ - const uint8_t *od=&dither[0][0]; - const uint8_t *end=&dither[height][0]; - width = (width+7)&~7; - dst_stride-=width; - //src_stride=(src_stride-width)*2; - __asm__ volatile( - "mov %5, %%"REG_d" \n\t" - "mov %6, %%"REG_S" \n\t" - "mov %7, %%"REG_D" \n\t" - "mov %1, %%"REG_a" \n\t" - "movd %%"REG_d", %%mm5 \n\t" - "xor $-1, %%"REG_d" \n\t" - "mov %%"REG_a", %%"REG_c" \n\t" - "add $7, %%"REG_d" \n\t" - "sub %0, %%"REG_c" \n\t" - "add %%"REG_c", %%"REG_c" \n\t" - "movd %%"REG_d", %%mm2 \n\t" - "mov %%"REG_c", %1 \n\t" - "mov %2, %%"REG_d" \n\t" - "shl $5, %%"REG_a" \n\t" - - "2: \n\t" - "movq (%%"REG_d"), %%mm3 \n\t" - "movq %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - "punpcklbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm4 \n\t" - "mov %0, %%"REG_c" \n\t" - "psraw %%mm5, %%mm3 \n\t" - "psraw %%mm5, %%mm4 \n\t" - "1: \n\t" - "movq (%%"REG_S"), %%mm0 \n\t" - "movq 8(%%"REG_S"), %%mm1 \n\t" - "paddw %%mm3, %%mm0 \n\t" - - "paddw (%%"REG_S",%%"REG_a",), %%mm0 \n\t" - "paddw %%mm4, %%mm1 \n\t" - "movq 8(%%"REG_S",%%"REG_a",), %%mm6 \n\t" - - "movq %%mm7, (%%"REG_S",%%"REG_a",) \n\t" - "psraw %%mm2, %%mm0 \n\t" - "paddw %%mm6, %%mm1 \n\t" - - "movq %%mm7, 8(%%"REG_S",%%"REG_a",) \n\t" - "psraw %%mm2, %%mm1 \n\t" - "packuswb %%mm1, %%mm0 \n\t" - - "movq %%mm0, (%%"REG_D") \n\t" - "add $16, %%"REG_S" \n\t" - "add $8, %%"REG_D" \n\t" - "sub $8, %%"REG_c" \n\t" - "jg 1b \n\t" - "add %1, %%"REG_S" \n\t" - "add $8, %%"REG_d" \n\t" - "add %3, %%"REG_D" \n\t" - "cmp %4, %%"REG_d" \n\t" - "jl 2b \n\t" - - : - : "m" (width), "m" (src_stride), "erm" (od), "m" (dst_stride), "erm" (end), - "m" (log2_scale), "m" (src), "m" (dst) //input - : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_D, "%"REG_S - ); -} - -static void mul_thrmat_mmx(struct vf_priv_s *p, int q) -{ - uint64_t *adr=&p->threshold_mtx_noq[0]; - __asm__ volatile( - "movd %0, %%mm7 \n\t" - "add $8*8*2, %%"REG_D" \n\t" - "movq 0*8(%%"REG_S"), %%mm0 \n\t" - "punpcklwd %%mm7, %%mm7 \n\t" - "movq 1*8(%%"REG_S"), %%mm1 \n\t" - "punpckldq %%mm7, %%mm7 \n\t" - "pmullw %%mm7, %%mm0 \n\t" - - "movq 2*8(%%"REG_S"), %%mm2 \n\t" - "pmullw %%mm7, %%mm1 \n\t" - - "movq 3*8(%%"REG_S"), %%mm3 \n\t" - "pmullw %%mm7, %%mm2 \n\t" - - "movq %%mm0, 0*8(%%"REG_D") \n\t" - "movq 4*8(%%"REG_S"), %%mm4 \n\t" - "pmullw %%mm7, %%mm3 \n\t" - - "movq %%mm1, 1*8(%%"REG_D") \n\t" - "movq 5*8(%%"REG_S"), %%mm5 \n\t" - "pmullw %%mm7, %%mm4 \n\t" - - "movq %%mm2, 2*8(%%"REG_D") \n\t" - "movq 6*8(%%"REG_S"), %%mm6 \n\t" - "pmullw %%mm7, %%mm5 \n\t" - - "movq %%mm3, 3*8(%%"REG_D") \n\t" - "movq 7*8+0*8(%%"REG_S"), %%mm0 \n\t" - "pmullw %%mm7, %%mm6 \n\t" - - "movq %%mm4, 4*8(%%"REG_D") \n\t" - "movq 7*8+1*8(%%"REG_S"), %%mm1 \n\t" - "pmullw %%mm7, %%mm0 \n\t" - - "movq %%mm5, 5*8(%%"REG_D") \n\t" - "movq 7*8+2*8(%%"REG_S"), %%mm2 \n\t" - "pmullw %%mm7, %%mm1 \n\t" - - "movq %%mm6, 6*8(%%"REG_D") \n\t" - "movq 7*8+3*8(%%"REG_S"), %%mm3 \n\t" - "pmullw %%mm7, %%mm2 \n\t" - - "movq %%mm0, 7*8+0*8(%%"REG_D") \n\t" - "movq 7*8+4*8(%%"REG_S"), %%mm4 \n\t" - "pmullw %%mm7, %%mm3 \n\t" - - "movq %%mm1, 7*8+1*8(%%"REG_D") \n\t" - "movq 7*8+5*8(%%"REG_S"), %%mm5 \n\t" - "pmullw %%mm7, %%mm4 \n\t" - - "movq %%mm2, 7*8+2*8(%%"REG_D") \n\t" - "movq 7*8+6*8(%%"REG_S"), %%mm6 \n\t" - "pmullw %%mm7, %%mm5 \n\t" - - "movq %%mm3, 7*8+3*8(%%"REG_D") \n\t" - "movq 14*8+0*8(%%"REG_S"), %%mm0 \n\t" - "pmullw %%mm7, %%mm6 \n\t" - - "movq %%mm4, 7*8+4*8(%%"REG_D") \n\t" - "movq 14*8+1*8(%%"REG_S"), %%mm1 \n\t" - "pmullw %%mm7, %%mm0 \n\t" - - "movq %%mm5, 7*8+5*8(%%"REG_D") \n\t" - "pmullw %%mm7, %%mm1 \n\t" - - "movq %%mm6, 7*8+6*8(%%"REG_D") \n\t" - "movq %%mm0, 14*8+0*8(%%"REG_D") \n\t" - "movq %%mm1, 14*8+1*8(%%"REG_D") \n\t" - - : "+g" (q), "+S" (adr), "+D" (adr) - : - ); -} - -static void column_fidct_mmx(int16_t* thr_adr, DCTELEM *data, DCTELEM *output, int cnt); -static void row_idct_mmx(DCTELEM* workspace, - int16_t* output_adr, int output_stride, int cnt); -static void row_fdct_mmx(DCTELEM *data, const uint8_t *pixels, int line_size, int cnt); - -#define store_slice_s store_slice_mmx -#define store_slice2_s store_slice2_mmx -#define mul_thrmat_s mul_thrmat_mmx -#define column_fidct_s column_fidct_mmx -#define row_idct_s row_idct_mmx -#define row_fdct_s row_fdct_mmx -#endif // HAVE_MMX - -static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, - int dst_stride, int src_stride, - int width, int height, - uint8_t *qp_store, int qp_stride, int is_luma) -{ - int x, x0, y, es, qy, t; - const int stride= is_luma ? p->temp_stride : (width+16);//((width+16+15)&(~15)) - const int step=6-p->log2_count; - const int qps= 3 + is_luma; - int32_t __attribute__((aligned(32))) block_align[4*8*BLOCKSZ+ 4*8*BLOCKSZ]; - DCTELEM *block= (DCTELEM *)block_align; - DCTELEM *block3=(DCTELEM *)(block_align+4*8*BLOCKSZ); - - memset(block3, 0, 4*8*BLOCKSZ); - - //p->src=src-src_stride*8-8;//! - if (!src || !dst) return; // HACK avoid crash for Y8 colourspace - for(y=0; ysrc + index, src + y*src_stride, width);//this line can be avoided by using DR & user fr.buffers - for(x=0; x<8; x++){ - p->src[index - x - 1]= p->src[index + x ]; - p->src[index + width + x ]= p->src[index + width - x - 1]; - } - } - for(y=0; y<8; y++){ - fast_memcpy(p->src + ( 7-y)*stride, p->src + ( y+8)*stride, stride); - fast_memcpy(p->src + (height+8+y)*stride, p->src + (height-y+7)*stride, stride); - } - //FIXME (try edge emu) - - for(y=8; y<24; y++) - memset(p->temp+ 8 +y*stride, 0,width*sizeof(int16_t)); - - for(y=step; yheight-1) qy=height-1; - if (qy<0) qy=0; - qy=(qy>>qps)*qp_stride; - row_fdct_s(block, p->src + y*stride +2-(y&1), stride, 2); - for(x0=0; x0src + y*stride+8+x0 +2-(y&1), stride, 2*(BLOCKSZ-1)); - if(p->qp) - column_fidct_s((int16_t*)(&p->threshold_mtx[0]), block+0*8, block3+0*8, 8*(BLOCKSZ-1)); //yes, this is a HOTSPOT - else - for (x=0; x<8*(BLOCKSZ-1); x+=8) { - t=x+x0-2; //correct t=x+x0-2-(y&1), but its the same - if (t<0) t=0;//t always < width-2 - t=qp_store[qy+(t>>qps)]; - t=norm_qscale(t, p->mpeg2); - if (t!=p->prev_q) p->prev_q=t, mul_thrmat_s(p, t); - column_fidct_s((int16_t*)(&p->threshold_mtx[0]), block+x*8, block3+x*8, 8); //yes, this is a HOTSPOT - } - row_idct_s(block3+0*8, p->temp + (y&15)*stride+x0+2-(y&1), stride, 2*(BLOCKSZ-1)); - memmove(block, block+(BLOCKSZ-1)*64, 8*8*sizeof(DCTELEM)); //cycling - memmove(block3, block3+(BLOCKSZ-1)*64, 6*8*sizeof(DCTELEM)); - } - // - es=width+8-x0; // 8, ... - if (es>8) - row_fdct_s(block+8*8, p->src + y*stride+8+x0 +2-(y&1), stride, (es-4)>>2); - column_fidct_s((int16_t*)(&p->threshold_mtx[0]), block, block3, es&(~1)); - row_idct_s(block3+0*8, p->temp + (y&15)*stride+x0+2-(y&1), stride, es>>2); - {const int y1=y-8+step;//l5-7 l4-6 - if (!(y1&7) && y1) { - if (y1&8) store_slice_s(dst + (y1-8)*dst_stride, p->temp+ 8 +8*stride, - dst_stride, stride, width, 8, 5-p->log2_count); - else store_slice2_s(dst + (y1-8)*dst_stride, p->temp+ 8 +0*stride, - dst_stride, stride, width, 8, 5-p->log2_count); - } } - } - - if (y&7) { // == height & 7 - if (y&8) store_slice_s(dst + ((y-8)&~7)*dst_stride, p->temp+ 8 +8*stride, - dst_stride, stride, width, y&7, 5-p->log2_count); - else store_slice2_s(dst + ((y-8)&~7)*dst_stride, p->temp+ 8 +0*stride, - dst_stride, stride, width, y&7, 5-p->log2_count); - } -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - int h= (height+16+15)&(~15); - - vf->priv->temp_stride= (width+16+15)&(~15); - vf->priv->temp= (int16_t*)av_mallocz(vf->priv->temp_stride*3*8*sizeof(int16_t)); - //this can also be avoided, see above - vf->priv->src = (uint8_t*)av_malloc(vf->priv->temp_stride*h*sizeof(uint8_t)); - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi) -{ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags, mpi->width, mpi->height); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // no DR, so get a new image! hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->width,mpi->height); - vf_clone_mpi_attributes(dmpi, mpi); - }else{ - dmpi=vf->dmpi; - } - - vf->priv->mpeg2= mpi->qscale_type; - if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){ - int w = mpi->qstride; - int h = (mpi->h + 15) >> 4; - if (!w) { - w = (mpi->w + 15) >> 4; - h = 1; - } - if(!vf->priv->non_b_qp) - vf->priv->non_b_qp= malloc(w*h); - fast_memcpy(vf->priv->non_b_qp, mpi->qscale, w*h); - } - if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){ - char *qp_tab= vf->priv->non_b_qp; - if(vf->priv->bframes || !qp_tab) - qp_tab= mpi->qscale; - - if(qp_tab || vf->priv->qp){ - filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], - mpi->w, mpi->h, qp_tab, mpi->qstride, 1); - filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], - mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0); - filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], - mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0); - }else{ - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]); - memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]); - } - } - -#if HAVE_MMX - if(gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t"); -#endif -#if HAVE_MMX2 - if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t"); -#endif - return vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf) -{ - if(!vf->priv) return; - - av_free(vf->priv->temp); - vf->priv->temp= NULL; - av_free(vf->priv->src); - vf->priv->src= NULL; - //free(vf->priv->avctx); - //vf->priv->avctx= NULL; - free(vf->priv->non_b_qp); - vf->priv->non_b_qp= NULL; - - av_free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - switch(fmt){ - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf,fmt); - } - return 0; -} - -static int control(struct vf_instance *vf, int request, void* data) -{ - switch(request){ - case VFCTRL_QUERY_MAX_PP_LEVEL: - return 5; - case VFCTRL_SET_PP_LEVEL: - vf->priv->log2_count= *((unsigned int*)data); - if (vf->priv->log2_count < 4) vf->priv->log2_count=4; - return CONTROL_TRUE; - } - return vf_next_control(vf,request,data); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - int i=0, bias; - int custom_threshold_m[64]; - int log2c=-1; - - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->control= control; - vf->priv=av_mallocz(sizeof(struct vf_priv_s));//assumes align 16 ! - - //vf->priv->avctx= avcodec_alloc_context(); - //ff_dsputil_init(&vf->priv->dsp, vf->priv->avctx); - - vf->priv->log2_count= 4; - vf->priv->bframes = 0; - - if (args) sscanf(args, "%d:%d:%d:%d", &log2c, &vf->priv->qp, &i, &vf->priv->bframes); - - if( log2c >=4 && log2c <=5 ) - vf->priv->log2_count = log2c; - else if( log2c >= 6 ) - vf->priv->log2_count = 5; - - if(vf->priv->qp < 0) - vf->priv->qp = 0; - - if (i < -15) i = -15; - if (i > 32) i = 32; - - bias= (1<<4)+i; //regulable - vf->priv->prev_q=0; - // - for(i=0;i<64;i++) //FIXME: tune custom_threshold[] and remove this ! - custom_threshold_m[i]=(int)(custom_threshold[i]*(bias/71.)+ 0.5); - for(i=0;i<8;i++){ - vf->priv->threshold_mtx_noq[2*i]=(uint64_t)custom_threshold_m[i*8+2] - |(((uint64_t)custom_threshold_m[i*8+6])<<16) - |(((uint64_t)custom_threshold_m[i*8+0])<<32) - |(((uint64_t)custom_threshold_m[i*8+4])<<48); - vf->priv->threshold_mtx_noq[2*i+1]=(uint64_t)custom_threshold_m[i*8+5] - |(((uint64_t)custom_threshold_m[i*8+3])<<16) - |(((uint64_t)custom_threshold_m[i*8+1])<<32) - |(((uint64_t)custom_threshold_m[i*8+7])<<48); - } - - if (vf->priv->qp) vf->priv->prev_q=vf->priv->qp, mul_thrmat_s(vf->priv, vf->priv->qp); - - return 1; -} - -const vf_info_t vf_info_fspp = { - "fast simple postprocess", - "fspp", - "Michael Niedermayer, Nikolaj Poroshin", - "", - vf_open, - NULL -}; - -//==================================================================== -//Specific spp's dct, idct and threshold functions -//I'd prefer to have them in the separate file. - -//#define MANGLE(a) #a - -//typedef int16_t DCTELEM; //! only int16_t - -#define DCTSIZE 8 -#define DCTSIZE_S "8" - -#define FIX(x,s) ((int) ((x) * (1<>16) -#define THRESHOLD(r,x,t) if(((unsigned)((x)+t))>t*2) r=(x);else r=0; -#define DESCALE(x,n) (((x) + (1 << ((n)-1))) >> n) - -#if HAVE_MMX - -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_382683433)=FIX64(0.382683433, 14); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_541196100)=FIX64(0.541196100, 14); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_707106781)=FIX64(0.707106781, 14); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_306562965)=FIX64(1.306562965, 14); - -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_414213562_A)=FIX64(1.414213562, 14); - -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_847759065)=FIX64(1.847759065, 13); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_2_613125930)=FIX64(-2.613125930, 13); //- -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_414213562)=FIX64(1.414213562, 13); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_082392200)=FIX64(1.082392200, 13); -//for t3,t5,t7 == 0 shortcut -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_847759065)=FIX64(0.847759065, 14); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_566454497)=FIX64(0.566454497, 14); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_198912367)=FIX64(0.198912367, 14); - -DECLARE_ASM_CONST(8, uint64_t, MM_DESCALE_RND)=C64(4); -DECLARE_ASM_CONST(8, uint64_t, MM_2)=C64(2); - -#else /* !HAVE_MMX */ - -typedef int32_t int_simd16_t; -static const int16_t FIX_0_382683433=FIX(0.382683433, 14); -static const int16_t FIX_0_541196100=FIX(0.541196100, 14); -static const int16_t FIX_0_707106781=FIX(0.707106781, 14); -static const int16_t FIX_1_306562965=FIX(1.306562965, 14); -static const int16_t FIX_1_414213562_A=FIX(1.414213562, 14); -static const int16_t FIX_1_847759065=FIX(1.847759065, 13); -static const int16_t FIX_2_613125930=FIX(-2.613125930, 13); //- -static const int16_t FIX_1_414213562=FIX(1.414213562, 13); -static const int16_t FIX_1_082392200=FIX(1.082392200, 13); - -#endif - -#if !HAVE_MMX - -static void column_fidct_c(int16_t* thr_adr, DCTELEM *data, DCTELEM *output, int cnt) -{ - int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_simd16_t tmp10, tmp11, tmp12, tmp13; - int_simd16_t z1,z2,z3,z4,z5, z10, z11, z12, z13; - int_simd16_t d0, d1, d2, d3, d4, d5, d6, d7; - - DCTELEM* dataptr; - DCTELEM* wsptr; - int16_t *threshold; - int ctr; - - dataptr = data; - wsptr = output; - - for (; cnt > 0; cnt-=2) { //start positions - threshold=(int16_t*)thr_adr;//threshold_mtx - for (ctr = DCTSIZE; ctr > 0; ctr--) { - // Process columns from input, add to output. - tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; - tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; - - tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; - tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; - - tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; - tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; - - tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; - tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; - - // Even part of FDCT - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - d0 = tmp10 + tmp11; - d4 = tmp10 - tmp11; - - z1 = MULTIPLY16H((tmp12 + tmp13) <<2, FIX_0_707106781); - d2 = tmp13 + z1; - d6 = tmp13 - z1; - - // Even part of IDCT - - THRESHOLD(tmp0, d0, threshold[0*8]); - THRESHOLD(tmp1, d2, threshold[2*8]); - THRESHOLD(tmp2, d4, threshold[4*8]); - THRESHOLD(tmp3, d6, threshold[6*8]); - tmp0+=2; - tmp10 = (tmp0 + tmp2)>>2; - tmp11 = (tmp0 - tmp2)>>2; - - tmp13 = (tmp1 + tmp3)>>2; //+2 ! (psnr decides) - tmp12 = MULTIPLY16H((tmp1 - tmp3), FIX_1_414213562_A) - tmp13; //<<2 - - tmp0 = tmp10 + tmp13; //->temps - tmp3 = tmp10 - tmp13; //->temps - tmp1 = tmp11 + tmp12; //->temps - tmp2 = tmp11 - tmp12; //->temps - - // Odd part of FDCT - - tmp10 = tmp4 + tmp5; - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - z5 = MULTIPLY16H((tmp10 - tmp12)<<2, FIX_0_382683433); - z2 = MULTIPLY16H(tmp10 <<2, FIX_0_541196100) + z5; - z4 = MULTIPLY16H(tmp12 <<2, FIX_1_306562965) + z5; - z3 = MULTIPLY16H(tmp11 <<2, FIX_0_707106781); - - z11 = tmp7 + z3; - z13 = tmp7 - z3; - - d5 = z13 + z2; - d3 = z13 - z2; - d1 = z11 + z4; - d7 = z11 - z4; - - // Odd part of IDCT - - THRESHOLD(tmp4, d1, threshold[1*8]); - THRESHOLD(tmp5, d3, threshold[3*8]); - THRESHOLD(tmp6, d5, threshold[5*8]); - THRESHOLD(tmp7, d7, threshold[7*8]); - - //Simd version uses here a shortcut for the tmp5,tmp6,tmp7 == 0 - z13 = tmp6 + tmp5; - z10 = (tmp6 - tmp5)<<1; - z11 = tmp4 + tmp7; - z12 = (tmp4 - tmp7)<<1; - - tmp7 = (z11 + z13)>>2; //+2 ! - tmp11 = MULTIPLY16H((z11 - z13)<<1, FIX_1_414213562); - z5 = MULTIPLY16H(z10 + z12, FIX_1_847759065); - tmp10 = MULTIPLY16H(z12, FIX_1_082392200) - z5; - tmp12 = MULTIPLY16H(z10, FIX_2_613125930) + z5; // - !! - - tmp6 = tmp12 - tmp7; - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - wsptr[DCTSIZE*0]+= (tmp0 + tmp7); - wsptr[DCTSIZE*1]+= (tmp1 + tmp6); - wsptr[DCTSIZE*2]+= (tmp2 + tmp5); - wsptr[DCTSIZE*3]+= (tmp3 - tmp4); - wsptr[DCTSIZE*4]+= (tmp3 + tmp4); - wsptr[DCTSIZE*5]+= (tmp2 - tmp5); - wsptr[DCTSIZE*6]= (tmp1 - tmp6); - wsptr[DCTSIZE*7]= (tmp0 - tmp7); - // - dataptr++; //next column - wsptr++; - threshold++; - } - dataptr+=8; //skip each second start pos - wsptr +=8; - } -} - -#else /* HAVE_MMX */ - -static void column_fidct_mmx(int16_t* thr_adr, DCTELEM *data, DCTELEM *output, int cnt) -{ - uint64_t __attribute__((aligned(8))) temps[4]; - __asm__ volatile( - ASMALIGN(4) - "1: \n\t" - "movq "DCTSIZE_S"*0*2(%%"REG_S"), %%mm1 \n\t" - // - "movq "DCTSIZE_S"*3*2(%%"REG_S"), %%mm7 \n\t" - "movq %%mm1, %%mm0 \n\t" - - "paddw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm1 \n\t" //t0 - "movq %%mm7, %%mm3 \n\t" - - "paddw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm7 \n\t" //t3 - "movq %%mm1, %%mm5 \n\t" - - "movq "DCTSIZE_S"*1*2(%%"REG_S"), %%mm6 \n\t" - "psubw %%mm7, %%mm1 \n\t" //t13 - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "movq %%mm6, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm6 \n\t" //t1 - "paddw %%mm7, %%mm5 \n\t" //t10 - - "paddw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t2 - "movq %%mm6, %%mm7 \n\t" - - "paddw %%mm2, %%mm6 \n\t" //t11 - "psubw %%mm2, %%mm7 \n\t" //t12 - - "movq %%mm5, %%mm2 \n\t" - "paddw %%mm6, %%mm5 \n\t" //d0 - // i0 t13 t12 i3 i1 d0 - d4 - "psubw %%mm6, %%mm2 \n\t" //d4 - "paddw %%mm1, %%mm7 \n\t" - - "movq 4*16(%%"REG_d"), %%mm6 \n\t" - "psllw $2, %%mm7 \n\t" - - "psubw 0*16(%%"REG_d"), %%mm5 \n\t" - "psubw %%mm6, %%mm2 \n\t" - - "paddusw 0*16(%%"REG_d"), %%mm5 \n\t" - "paddusw %%mm6, %%mm2 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_707106781)", %%mm7 \n\t" - // - "paddw 0*16(%%"REG_d"), %%mm5 \n\t" - "paddw %%mm6, %%mm2 \n\t" - - "psubusw 0*16(%%"REG_d"), %%mm5 \n\t" - "psubusw %%mm6, %%mm2 \n\t" - -//This func is totally compute-bound, operates at huge speed. So, DC shortcut -// at this place isn't worthwhile due to BTB miss penalty (checked on Pent. 3). -//However, typical numbers: nondc - 29%%, dc - 46%%, zero - 25%%. All <> 0 case is very rare. - "paddw "MANGLE(MM_2)", %%mm5 \n\t" - "movq %%mm2, %%mm6 \n\t" - - "paddw %%mm5, %%mm2 \n\t" - "psubw %%mm6, %%mm5 \n\t" - - "movq %%mm1, %%mm6 \n\t" - "paddw %%mm7, %%mm1 \n\t" //d2 - - "psubw 2*16(%%"REG_d"), %%mm1 \n\t" - "psubw %%mm7, %%mm6 \n\t" //d6 - - "movq 6*16(%%"REG_d"), %%mm7 \n\t" - "psraw $2, %%mm5 \n\t" - - "paddusw 2*16(%%"REG_d"), %%mm1 \n\t" - "psubw %%mm7, %%mm6 \n\t" - // t7 d2 /t11 t4 t6 - d6 /t10 - - "paddw 2*16(%%"REG_d"), %%mm1 \n\t" - "paddusw %%mm7, %%mm6 \n\t" - - "psubusw 2*16(%%"REG_d"), %%mm1 \n\t" - "paddw %%mm7, %%mm6 \n\t" - - "psubw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm3 \n\t" - "psubusw %%mm7, %%mm6 \n\t" - - //movq [edi+"DCTSIZE_S"*2*2], mm1 - //movq [edi+"DCTSIZE_S"*6*2], mm6 - "movq %%mm1, %%mm7 \n\t" - "psraw $2, %%mm2 \n\t" - - "psubw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm4 \n\t" - "psubw %%mm6, %%mm1 \n\t" - - "psubw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm0 \n\t" - "paddw %%mm7, %%mm6 \n\t" //'t13 - - "psraw $2, %%mm6 \n\t" //paddw mm6, MM_2 !! --- - "movq %%mm2, %%mm7 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_414213562_A)", %%mm1 \n\t" - "paddw %%mm6, %%mm2 \n\t" //'t0 - - "movq %%mm2, 0*8+%3 \n\t" //! - "psubw %%mm6, %%mm7 \n\t" //'t3 - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "psubw %%mm6, %%mm1 \n\t" //'t12 - - "psubw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t5 - "movq %%mm5, %%mm6 \n\t" - - "movq %%mm7, 3*8+%3 \n\t" - "paddw %%mm2, %%mm3 \n\t" //t10 - - "paddw %%mm4, %%mm2 \n\t" //t11 - "paddw %%mm0, %%mm4 \n\t" //t12 - - "movq %%mm3, %%mm7 \n\t" - "psubw %%mm4, %%mm3 \n\t" - - "psllw $2, %%mm3 \n\t" - "psllw $2, %%mm7 \n\t" //opt for P6 - - "pmulhw "MANGLE(MM_FIX_0_382683433)", %%mm3 \n\t" - "psllw $2, %%mm4 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_541196100)", %%mm7 \n\t" - "psllw $2, %%mm2 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_306562965)", %%mm4 \n\t" - "paddw %%mm1, %%mm5 \n\t" //'t1 - - "pmulhw "MANGLE(MM_FIX_0_707106781)", %%mm2 \n\t" - "psubw %%mm1, %%mm6 \n\t" //'t2 - // t7 't12 't11 t4 t6 - 't13 't10 --- - - "paddw %%mm3, %%mm7 \n\t" //z2 - - "movq %%mm5, 1*8+%3 \n\t" - "paddw %%mm3, %%mm4 \n\t" //z4 - - "movq 3*16(%%"REG_d"), %%mm3 \n\t" - "movq %%mm0, %%mm1 \n\t" - - "movq %%mm6, 2*8+%3 \n\t" - "psubw %%mm2, %%mm1 \n\t" //z13 - -//=== - "paddw %%mm2, %%mm0 \n\t" //z11 - "movq %%mm1, %%mm5 \n\t" - - "movq 5*16(%%"REG_d"), %%mm2 \n\t" - "psubw %%mm7, %%mm1 \n\t" //d3 - - "paddw %%mm7, %%mm5 \n\t" //d5 - "psubw %%mm3, %%mm1 \n\t" - - "movq 1*16(%%"REG_d"), %%mm7 \n\t" - "psubw %%mm2, %%mm5 \n\t" - - "movq %%mm0, %%mm6 \n\t" - "paddw %%mm4, %%mm0 \n\t" //d1 - - "paddusw %%mm3, %%mm1 \n\t" - "psubw %%mm4, %%mm6 \n\t" //d7 - - // d1 d3 - - - d5 d7 - - "movq 7*16(%%"REG_d"), %%mm4 \n\t" - "psubw %%mm7, %%mm0 \n\t" - - "psubw %%mm4, %%mm6 \n\t" - "paddusw %%mm2, %%mm5 \n\t" - - "paddusw %%mm4, %%mm6 \n\t" - "paddw %%mm3, %%mm1 \n\t" - - "paddw %%mm2, %%mm5 \n\t" - "paddw %%mm4, %%mm6 \n\t" - - "psubusw %%mm3, %%mm1 \n\t" - "psubusw %%mm2, %%mm5 \n\t" - - "psubusw %%mm4, %%mm6 \n\t" - "movq %%mm1, %%mm4 \n\t" - - "por %%mm5, %%mm4 \n\t" - "paddusw %%mm7, %%mm0 \n\t" - - "por %%mm6, %%mm4 \n\t" - "paddw %%mm7, %%mm0 \n\t" - - "packssdw %%mm4, %%mm4 \n\t" - "psubusw %%mm7, %%mm0 \n\t" - - "movd %%mm4, %%"REG_a" \n\t" - "or %%"REG_a", %%"REG_a" \n\t" - "jnz 2f \n\t" - //movq [edi+"DCTSIZE_S"*3*2], mm1 - //movq [edi+"DCTSIZE_S"*5*2], mm5 - //movq [edi+"DCTSIZE_S"*1*2], mm0 - //movq [edi+"DCTSIZE_S"*7*2], mm6 - // t4 t5 - - - t6 t7 - - //--- t4 (mm0) may be <>0; mm1, mm5, mm6 == 0 -//Typical numbers: nondc - 19%%, dc - 26%%, zero - 55%%. zero case alone isn't worthwhile - "movq 0*8+%3, %%mm4 \n\t" - "movq %%mm0, %%mm1 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_847759065)", %%mm0 \n\t" //tmp6 - "movq %%mm1, %%mm2 \n\t" - - "movq "DCTSIZE_S"*0*2(%%"REG_D"), %%mm5 \n\t" - "movq %%mm2, %%mm3 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_566454497)", %%mm1 \n\t" //tmp5 - "paddw %%mm4, %%mm5 \n\t" - - "movq 1*8+%3, %%mm6 \n\t" - //paddw mm3, MM_2 - "psraw $2, %%mm3 \n\t" //tmp7 - - "pmulhw "MANGLE(MM_FIX_0_198912367)", %%mm2 \n\t" //-tmp4 - "psubw %%mm3, %%mm4 \n\t" - - "movq "DCTSIZE_S"*1*2(%%"REG_D"), %%mm7 \n\t" - "paddw %%mm3, %%mm5 \n\t" - - "movq %%mm4, "DCTSIZE_S"*7*2(%%"REG_D") \n\t" - "paddw %%mm6, %%mm7 \n\t" - - "movq 2*8+%3, %%mm3 \n\t" - "psubw %%mm0, %%mm6 \n\t" - - "movq "DCTSIZE_S"*2*2(%%"REG_D"), %%mm4 \n\t" - "paddw %%mm0, %%mm7 \n\t" - - "movq %%mm5, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "paddw %%mm3, %%mm4 \n\t" - - "movq %%mm6, "DCTSIZE_S"*6*2(%%"REG_D") \n\t" - "psubw %%mm1, %%mm3 \n\t" - - "movq "DCTSIZE_S"*5*2(%%"REG_D"), %%mm5 \n\t" - "paddw %%mm1, %%mm4 \n\t" - - "movq "DCTSIZE_S"*3*2(%%"REG_D"), %%mm6 \n\t" - "paddw %%mm3, %%mm5 \n\t" - - "movq 3*8+%3, %%mm0 \n\t" - "add $8, %%"REG_S" \n\t" - - "movq %%mm7, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "paddw %%mm0, %%mm6 \n\t" - - "movq %%mm4, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "psubw %%mm2, %%mm0 \n\t" - - "movq "DCTSIZE_S"*4*2(%%"REG_D"), %%mm7 \n\t" - "paddw %%mm2, %%mm6 \n\t" - - "movq %%mm5, "DCTSIZE_S"*5*2(%%"REG_D") \n\t" - "paddw %%mm0, %%mm7 \n\t" - - "movq %%mm6, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - - "movq %%mm7, "DCTSIZE_S"*4*2(%%"REG_D") \n\t" - "add $8, %%"REG_D" \n\t" - "jmp 4f \n\t" - - "2: \n\t" - //--- non DC2 - //psraw mm1, 2 w/o it -> offset. thr1, thr1, thr1 (actually thr1, thr1, thr1-1) - //psraw mm5, 2 - //psraw mm0, 2 - //psraw mm6, 2 - "movq %%mm5, %%mm3 \n\t" - "psubw %%mm1, %%mm5 \n\t" - - "psllw $1, %%mm5 \n\t" //'z10 - "paddw %%mm1, %%mm3 \n\t" //'z13 - - "movq %%mm0, %%mm2 \n\t" - "psubw %%mm6, %%mm0 \n\t" - - "movq %%mm5, %%mm1 \n\t" - "psllw $1, %%mm0 \n\t" //'z12 - - "pmulhw "MANGLE(MM_FIX_2_613125930)", %%mm1 \n\t" //- - "paddw %%mm0, %%mm5 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_847759065)", %%mm5 \n\t" //'z5 - "paddw %%mm6, %%mm2 \n\t" //'z11 - - "pmulhw "MANGLE(MM_FIX_1_082392200)", %%mm0 \n\t" - "movq %%mm2, %%mm7 \n\t" - - //--- - "movq 0*8+%3, %%mm4 \n\t" - "psubw %%mm3, %%mm2 \n\t" - - "psllw $1, %%mm2 \n\t" - "paddw %%mm3, %%mm7 \n\t" //'t7 - - "pmulhw "MANGLE(MM_FIX_1_414213562)", %%mm2 \n\t" //'t11 - "movq %%mm4, %%mm6 \n\t" - //paddw mm7, MM_2 - "psraw $2, %%mm7 \n\t" - - "paddw "DCTSIZE_S"*0*2(%%"REG_D"), %%mm4 \n\t" - "psubw %%mm7, %%mm6 \n\t" - - "movq 1*8+%3, %%mm3 \n\t" - "paddw %%mm7, %%mm4 \n\t" - - "movq %%mm6, "DCTSIZE_S"*7*2(%%"REG_D") \n\t" - "paddw %%mm5, %%mm1 \n\t" //'t12 - - "movq %%mm4, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "psubw %%mm7, %%mm1 \n\t" //'t6 - - "movq 2*8+%3, %%mm7 \n\t" - "psubw %%mm5, %%mm0 \n\t" //'t10 - - "movq 3*8+%3, %%mm6 \n\t" - "movq %%mm3, %%mm5 \n\t" - - "paddw "DCTSIZE_S"*1*2(%%"REG_D"), %%mm3 \n\t" - "psubw %%mm1, %%mm5 \n\t" - - "psubw %%mm1, %%mm2 \n\t" //'t5 - "paddw %%mm1, %%mm3 \n\t" - - "movq %%mm5, "DCTSIZE_S"*6*2(%%"REG_D") \n\t" - "movq %%mm7, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*2*2(%%"REG_D"), %%mm7 \n\t" - "psubw %%mm2, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*5*2(%%"REG_D"), %%mm4 \n\t" - "paddw %%mm2, %%mm7 \n\t" - - "movq %%mm3, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "paddw %%mm2, %%mm0 \n\t" //'t4 - - // 't4 't6 't5 - - - - 't7 - "movq %%mm7, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "movq %%mm6, %%mm1 \n\t" - - "paddw "DCTSIZE_S"*4*2(%%"REG_D"), %%mm6 \n\t" - "psubw %%mm0, %%mm1 \n\t" - - "paddw "DCTSIZE_S"*3*2(%%"REG_D"), %%mm1 \n\t" - "paddw %%mm0, %%mm6 \n\t" - - "movq %%mm4, "DCTSIZE_S"*5*2(%%"REG_D") \n\t" - "add $8, %%"REG_S" \n\t" - - "movq %%mm6, "DCTSIZE_S"*4*2(%%"REG_D") \n\t" - - "movq %%mm1, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - "add $8, %%"REG_D" \n\t" - - "4: \n\t" -//=part 2 (the same)=========================================================== - "movq "DCTSIZE_S"*0*2(%%"REG_S"), %%mm1 \n\t" - // - "movq "DCTSIZE_S"*3*2(%%"REG_S"), %%mm7 \n\t" - "movq %%mm1, %%mm0 \n\t" - - "paddw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm1 \n\t" //t0 - "movq %%mm7, %%mm3 \n\t" - - "paddw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm7 \n\t" //t3 - "movq %%mm1, %%mm5 \n\t" - - "movq "DCTSIZE_S"*1*2(%%"REG_S"), %%mm6 \n\t" - "psubw %%mm7, %%mm1 \n\t" //t13 - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "movq %%mm6, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm6 \n\t" //t1 - "paddw %%mm7, %%mm5 \n\t" //t10 - - "paddw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t2 - "movq %%mm6, %%mm7 \n\t" - - "paddw %%mm2, %%mm6 \n\t" //t11 - "psubw %%mm2, %%mm7 \n\t" //t12 - - "movq %%mm5, %%mm2 \n\t" - "paddw %%mm6, %%mm5 \n\t" //d0 - // i0 t13 t12 i3 i1 d0 - d4 - "psubw %%mm6, %%mm2 \n\t" //d4 - "paddw %%mm1, %%mm7 \n\t" - - "movq 1*8+4*16(%%"REG_d"), %%mm6 \n\t" - "psllw $2, %%mm7 \n\t" - - "psubw 1*8+0*16(%%"REG_d"), %%mm5 \n\t" - "psubw %%mm6, %%mm2 \n\t" - - "paddusw 1*8+0*16(%%"REG_d"), %%mm5 \n\t" - "paddusw %%mm6, %%mm2 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_707106781)", %%mm7 \n\t" - // - "paddw 1*8+0*16(%%"REG_d"), %%mm5 \n\t" - "paddw %%mm6, %%mm2 \n\t" - - "psubusw 1*8+0*16(%%"REG_d"), %%mm5 \n\t" - "psubusw %%mm6, %%mm2 \n\t" - -//This func is totally compute-bound, operates at huge speed. So, DC shortcut -// at this place isn't worthwhile due to BTB miss penalty (checked on Pent. 3). -//However, typical numbers: nondc - 29%%, dc - 46%%, zero - 25%%. All <> 0 case is very rare. - "paddw "MANGLE(MM_2)", %%mm5 \n\t" - "movq %%mm2, %%mm6 \n\t" - - "paddw %%mm5, %%mm2 \n\t" - "psubw %%mm6, %%mm5 \n\t" - - "movq %%mm1, %%mm6 \n\t" - "paddw %%mm7, %%mm1 \n\t" //d2 - - "psubw 1*8+2*16(%%"REG_d"), %%mm1 \n\t" - "psubw %%mm7, %%mm6 \n\t" //d6 - - "movq 1*8+6*16(%%"REG_d"), %%mm7 \n\t" - "psraw $2, %%mm5 \n\t" - - "paddusw 1*8+2*16(%%"REG_d"), %%mm1 \n\t" - "psubw %%mm7, %%mm6 \n\t" - // t7 d2 /t11 t4 t6 - d6 /t10 - - "paddw 1*8+2*16(%%"REG_d"), %%mm1 \n\t" - "paddusw %%mm7, %%mm6 \n\t" - - "psubusw 1*8+2*16(%%"REG_d"), %%mm1 \n\t" - "paddw %%mm7, %%mm6 \n\t" - - "psubw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm3 \n\t" - "psubusw %%mm7, %%mm6 \n\t" - - //movq [edi+"DCTSIZE_S"*2*2], mm1 - //movq [edi+"DCTSIZE_S"*6*2], mm6 - "movq %%mm1, %%mm7 \n\t" - "psraw $2, %%mm2 \n\t" - - "psubw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm4 \n\t" - "psubw %%mm6, %%mm1 \n\t" - - "psubw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm0 \n\t" - "paddw %%mm7, %%mm6 \n\t" //'t13 - - "psraw $2, %%mm6 \n\t" //paddw mm6, MM_2 !! --- - "movq %%mm2, %%mm7 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_414213562_A)", %%mm1 \n\t" - "paddw %%mm6, %%mm2 \n\t" //'t0 - - "movq %%mm2, 0*8+%3 \n\t" //! - "psubw %%mm6, %%mm7 \n\t" //'t3 - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "psubw %%mm6, %%mm1 \n\t" //'t12 - - "psubw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t5 - "movq %%mm5, %%mm6 \n\t" - - "movq %%mm7, 3*8+%3 \n\t" - "paddw %%mm2, %%mm3 \n\t" //t10 - - "paddw %%mm4, %%mm2 \n\t" //t11 - "paddw %%mm0, %%mm4 \n\t" //t12 - - "movq %%mm3, %%mm7 \n\t" - "psubw %%mm4, %%mm3 \n\t" - - "psllw $2, %%mm3 \n\t" - "psllw $2, %%mm7 \n\t" //opt for P6 - - "pmulhw "MANGLE(MM_FIX_0_382683433)", %%mm3 \n\t" - "psllw $2, %%mm4 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_541196100)", %%mm7 \n\t" - "psllw $2, %%mm2 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_306562965)", %%mm4 \n\t" - "paddw %%mm1, %%mm5 \n\t" //'t1 - - "pmulhw "MANGLE(MM_FIX_0_707106781)", %%mm2 \n\t" - "psubw %%mm1, %%mm6 \n\t" //'t2 - // t7 't12 't11 t4 t6 - 't13 't10 --- - - "paddw %%mm3, %%mm7 \n\t" //z2 - - "movq %%mm5, 1*8+%3 \n\t" - "paddw %%mm3, %%mm4 \n\t" //z4 - - "movq 1*8+3*16(%%"REG_d"), %%mm3 \n\t" - "movq %%mm0, %%mm1 \n\t" - - "movq %%mm6, 2*8+%3 \n\t" - "psubw %%mm2, %%mm1 \n\t" //z13 - -//=== - "paddw %%mm2, %%mm0 \n\t" //z11 - "movq %%mm1, %%mm5 \n\t" - - "movq 1*8+5*16(%%"REG_d"), %%mm2 \n\t" - "psubw %%mm7, %%mm1 \n\t" //d3 - - "paddw %%mm7, %%mm5 \n\t" //d5 - "psubw %%mm3, %%mm1 \n\t" - - "movq 1*8+1*16(%%"REG_d"), %%mm7 \n\t" - "psubw %%mm2, %%mm5 \n\t" - - "movq %%mm0, %%mm6 \n\t" - "paddw %%mm4, %%mm0 \n\t" //d1 - - "paddusw %%mm3, %%mm1 \n\t" - "psubw %%mm4, %%mm6 \n\t" //d7 - - // d1 d3 - - - d5 d7 - - "movq 1*8+7*16(%%"REG_d"), %%mm4 \n\t" - "psubw %%mm7, %%mm0 \n\t" - - "psubw %%mm4, %%mm6 \n\t" - "paddusw %%mm2, %%mm5 \n\t" - - "paddusw %%mm4, %%mm6 \n\t" - "paddw %%mm3, %%mm1 \n\t" - - "paddw %%mm2, %%mm5 \n\t" - "paddw %%mm4, %%mm6 \n\t" - - "psubusw %%mm3, %%mm1 \n\t" - "psubusw %%mm2, %%mm5 \n\t" - - "psubusw %%mm4, %%mm6 \n\t" - "movq %%mm1, %%mm4 \n\t" - - "por %%mm5, %%mm4 \n\t" - "paddusw %%mm7, %%mm0 \n\t" - - "por %%mm6, %%mm4 \n\t" - "paddw %%mm7, %%mm0 \n\t" - - "packssdw %%mm4, %%mm4 \n\t" - "psubusw %%mm7, %%mm0 \n\t" - - "movd %%mm4, %%"REG_a" \n\t" - "or %%"REG_a", %%"REG_a" \n\t" - "jnz 3f \n\t" - //movq [edi+"DCTSIZE_S"*3*2], mm1 - //movq [edi+"DCTSIZE_S"*5*2], mm5 - //movq [edi+"DCTSIZE_S"*1*2], mm0 - //movq [edi+"DCTSIZE_S"*7*2], mm6 - // t4 t5 - - - t6 t7 - - //--- t4 (mm0) may be <>0; mm1, mm5, mm6 == 0 -//Typical numbers: nondc - 19%%, dc - 26%%, zero - 55%%. zero case alone isn't worthwhile - "movq 0*8+%3, %%mm4 \n\t" - "movq %%mm0, %%mm1 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_847759065)", %%mm0 \n\t" //tmp6 - "movq %%mm1, %%mm2 \n\t" - - "movq "DCTSIZE_S"*0*2(%%"REG_D"), %%mm5 \n\t" - "movq %%mm2, %%mm3 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_566454497)", %%mm1 \n\t" //tmp5 - "paddw %%mm4, %%mm5 \n\t" - - "movq 1*8+%3, %%mm6 \n\t" - //paddw mm3, MM_2 - "psraw $2, %%mm3 \n\t" //tmp7 - - "pmulhw "MANGLE(MM_FIX_0_198912367)", %%mm2 \n\t" //-tmp4 - "psubw %%mm3, %%mm4 \n\t" - - "movq "DCTSIZE_S"*1*2(%%"REG_D"), %%mm7 \n\t" - "paddw %%mm3, %%mm5 \n\t" - - "movq %%mm4, "DCTSIZE_S"*7*2(%%"REG_D") \n\t" - "paddw %%mm6, %%mm7 \n\t" - - "movq 2*8+%3, %%mm3 \n\t" - "psubw %%mm0, %%mm6 \n\t" - - "movq "DCTSIZE_S"*2*2(%%"REG_D"), %%mm4 \n\t" - "paddw %%mm0, %%mm7 \n\t" - - "movq %%mm5, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "paddw %%mm3, %%mm4 \n\t" - - "movq %%mm6, "DCTSIZE_S"*6*2(%%"REG_D") \n\t" - "psubw %%mm1, %%mm3 \n\t" - - "movq "DCTSIZE_S"*5*2(%%"REG_D"), %%mm5 \n\t" - "paddw %%mm1, %%mm4 \n\t" - - "movq "DCTSIZE_S"*3*2(%%"REG_D"), %%mm6 \n\t" - "paddw %%mm3, %%mm5 \n\t" - - "movq 3*8+%3, %%mm0 \n\t" - "add $24, %%"REG_S" \n\t" - - "movq %%mm7, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "paddw %%mm0, %%mm6 \n\t" - - "movq %%mm4, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "psubw %%mm2, %%mm0 \n\t" - - "movq "DCTSIZE_S"*4*2(%%"REG_D"), %%mm7 \n\t" - "paddw %%mm2, %%mm6 \n\t" - - "movq %%mm5, "DCTSIZE_S"*5*2(%%"REG_D") \n\t" - "paddw %%mm0, %%mm7 \n\t" - - "movq %%mm6, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - - "movq %%mm7, "DCTSIZE_S"*4*2(%%"REG_D") \n\t" - "add $24, %%"REG_D" \n\t" - "sub $2, %%"REG_c" \n\t" - "jnz 1b \n\t" - "jmp 5f \n\t" - - "3: \n\t" - //--- non DC2 - //psraw mm1, 2 w/o it -> offset. thr1, thr1, thr1 (actually thr1, thr1, thr1-1) - //psraw mm5, 2 - //psraw mm0, 2 - //psraw mm6, 2 - "movq %%mm5, %%mm3 \n\t" - "psubw %%mm1, %%mm5 \n\t" - - "psllw $1, %%mm5 \n\t" //'z10 - "paddw %%mm1, %%mm3 \n\t" //'z13 - - "movq %%mm0, %%mm2 \n\t" - "psubw %%mm6, %%mm0 \n\t" - - "movq %%mm5, %%mm1 \n\t" - "psllw $1, %%mm0 \n\t" //'z12 - - "pmulhw "MANGLE(MM_FIX_2_613125930)", %%mm1 \n\t" //- - "paddw %%mm0, %%mm5 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_847759065)", %%mm5 \n\t" //'z5 - "paddw %%mm6, %%mm2 \n\t" //'z11 - - "pmulhw "MANGLE(MM_FIX_1_082392200)", %%mm0 \n\t" - "movq %%mm2, %%mm7 \n\t" - - //--- - "movq 0*8+%3, %%mm4 \n\t" - "psubw %%mm3, %%mm2 \n\t" - - "psllw $1, %%mm2 \n\t" - "paddw %%mm3, %%mm7 \n\t" //'t7 - - "pmulhw "MANGLE(MM_FIX_1_414213562)", %%mm2 \n\t" //'t11 - "movq %%mm4, %%mm6 \n\t" - //paddw mm7, MM_2 - "psraw $2, %%mm7 \n\t" - - "paddw "DCTSIZE_S"*0*2(%%"REG_D"), %%mm4 \n\t" - "psubw %%mm7, %%mm6 \n\t" - - "movq 1*8+%3, %%mm3 \n\t" - "paddw %%mm7, %%mm4 \n\t" - - "movq %%mm6, "DCTSIZE_S"*7*2(%%"REG_D") \n\t" - "paddw %%mm5, %%mm1 \n\t" //'t12 - - "movq %%mm4, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "psubw %%mm7, %%mm1 \n\t" //'t6 - - "movq 2*8+%3, %%mm7 \n\t" - "psubw %%mm5, %%mm0 \n\t" //'t10 - - "movq 3*8+%3, %%mm6 \n\t" - "movq %%mm3, %%mm5 \n\t" - - "paddw "DCTSIZE_S"*1*2(%%"REG_D"), %%mm3 \n\t" - "psubw %%mm1, %%mm5 \n\t" - - "psubw %%mm1, %%mm2 \n\t" //'t5 - "paddw %%mm1, %%mm3 \n\t" - - "movq %%mm5, "DCTSIZE_S"*6*2(%%"REG_D") \n\t" - "movq %%mm7, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*2*2(%%"REG_D"), %%mm7 \n\t" - "psubw %%mm2, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*5*2(%%"REG_D"), %%mm4 \n\t" - "paddw %%mm2, %%mm7 \n\t" - - "movq %%mm3, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "paddw %%mm2, %%mm0 \n\t" //'t4 - - // 't4 't6 't5 - - - - 't7 - "movq %%mm7, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "movq %%mm6, %%mm1 \n\t" - - "paddw "DCTSIZE_S"*4*2(%%"REG_D"), %%mm6 \n\t" - "psubw %%mm0, %%mm1 \n\t" - - "paddw "DCTSIZE_S"*3*2(%%"REG_D"), %%mm1 \n\t" - "paddw %%mm0, %%mm6 \n\t" - - "movq %%mm4, "DCTSIZE_S"*5*2(%%"REG_D") \n\t" - "add $24, %%"REG_S" \n\t" - - "movq %%mm6, "DCTSIZE_S"*4*2(%%"REG_D") \n\t" - - "movq %%mm1, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - "add $24, %%"REG_D" \n\t" - "sub $2, %%"REG_c" \n\t" - "jnz 1b \n\t" - "5: \n\t" - - : "+S"(data), "+D"(output), "+c"(cnt), "=o"(temps) - : "d"(thr_adr) - : "%"REG_a - ); -} - -#endif // HAVE_MMX - -#if !HAVE_MMX - -static void row_idct_c(DCTELEM* workspace, - int16_t* output_adr, int output_stride, int cnt) -{ - int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_simd16_t tmp10, tmp11, tmp12, tmp13; - int_simd16_t z5, z10, z11, z12, z13; - int16_t* outptr; - DCTELEM* wsptr; - - cnt*=4; - wsptr = workspace; - outptr = output_adr; - for (; cnt > 0; cnt--) { - // Even part - //Simd version reads 4x4 block and transposes it - tmp10 = ( wsptr[2] + wsptr[3]); - tmp11 = ( wsptr[2] - wsptr[3]); - - tmp13 = ( wsptr[0] + wsptr[1]); - tmp12 = (MULTIPLY16H( wsptr[0] - wsptr[1], FIX_1_414213562_A)<<2) - tmp13;//this shift order to avoid overflow - - tmp0 = tmp10 + tmp13; //->temps - tmp3 = tmp10 - tmp13; //->temps - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - // Odd part - //Also transpose, with previous: - // ---- ---- |||| - // ---- ---- idct |||| - // ---- ---- ---> |||| - // ---- ---- |||| - z13 = wsptr[4] + wsptr[5]; - z10 = wsptr[4] - wsptr[5]; - z11 = wsptr[6] + wsptr[7]; - z12 = wsptr[6] - wsptr[7]; - - tmp7 = z11 + z13; - tmp11 = MULTIPLY16H(z11 - z13, FIX_1_414213562); - - z5 = MULTIPLY16H(z10 + z12, FIX_1_847759065); - tmp10 = MULTIPLY16H(z12, FIX_1_082392200) - z5; - tmp12 = MULTIPLY16H(z10, FIX_2_613125930) + z5; // - FIX_ - - tmp6 = (tmp12<<3) - tmp7; - tmp5 = (tmp11<<3) - tmp6; - tmp4 = (tmp10<<3) + tmp5; - - // Final output stage: descale and write column - outptr[0*output_stride]+= DESCALE(tmp0 + tmp7, 3); - outptr[1*output_stride]+= DESCALE(tmp1 + tmp6, 3); - outptr[2*output_stride]+= DESCALE(tmp2 + tmp5, 3); - outptr[3*output_stride]+= DESCALE(tmp3 - tmp4, 3); - outptr[4*output_stride]+= DESCALE(tmp3 + tmp4, 3); - outptr[5*output_stride]+= DESCALE(tmp2 - tmp5, 3); - outptr[6*output_stride]+= DESCALE(tmp1 - tmp6, 3); //no += ? - outptr[7*output_stride]+= DESCALE(tmp0 - tmp7, 3); //no += ? - outptr++; - - wsptr += DCTSIZE; // advance pointer to next row - } -} - -#else /* HAVE_MMX */ - -static void row_idct_mmx (DCTELEM* workspace, - int16_t* output_adr, int output_stride, int cnt) -{ - uint64_t __attribute__((aligned(8))) temps[4]; - __asm__ volatile( - "lea (%%"REG_a",%%"REG_a",2), %%"REG_d" \n\t" - "1: \n\t" - "movq "DCTSIZE_S"*0*2(%%"REG_S"), %%mm0 \n\t" - // - - "movq "DCTSIZE_S"*1*2(%%"REG_S"), %%mm1 \n\t" - "movq %%mm0, %%mm4 \n\t" - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "punpcklwd %%mm1, %%mm0 \n\t" - - "movq "DCTSIZE_S"*3*2(%%"REG_S"), %%mm3 \n\t" - "punpckhwd %%mm1, %%mm4 \n\t" - - //transpose 4x4 - "movq %%mm2, %%mm7 \n\t" - "punpcklwd %%mm3, %%mm2 \n\t" - - "movq %%mm0, %%mm6 \n\t" - "punpckldq %%mm2, %%mm0 \n\t" //0 - - "punpckhdq %%mm2, %%mm6 \n\t" //1 - "movq %%mm0, %%mm5 \n\t" - - "punpckhwd %%mm3, %%mm7 \n\t" - "psubw %%mm6, %%mm0 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_414213562_A)", %%mm0 \n\t" - "movq %%mm4, %%mm2 \n\t" - - "punpckldq %%mm7, %%mm4 \n\t" //2 - "paddw %%mm6, %%mm5 \n\t" - - "punpckhdq %%mm7, %%mm2 \n\t" //3 - "movq %%mm4, %%mm1 \n\t" - - "psllw $2, %%mm0 \n\t" - "paddw %%mm2, %%mm4 \n\t" //t10 - - "movq "DCTSIZE_S"*0*2+"DCTSIZE_S"(%%"REG_S"), %%mm3 \n\t" - "psubw %%mm2, %%mm1 \n\t" //t11 - - "movq "DCTSIZE_S"*1*2+"DCTSIZE_S"(%%"REG_S"), %%mm2 \n\t" - "psubw %%mm5, %%mm0 \n\t" - - "movq %%mm4, %%mm6 \n\t" - "paddw %%mm5, %%mm4 \n\t" //t0 - - "psubw %%mm5, %%mm6 \n\t" //t3 - "movq %%mm1, %%mm7 \n\t" - - "movq "DCTSIZE_S"*2*2+"DCTSIZE_S"(%%"REG_S"), %%mm5 \n\t" - "paddw %%mm0, %%mm1 \n\t" //t1 - - "movq %%mm4, 0*8+%3 \n\t" //t0 - "movq %%mm3, %%mm4 \n\t" - - "movq %%mm6, 1*8+%3 \n\t" //t3 - "punpcklwd %%mm2, %%mm3 \n\t" - - //transpose 4x4 - "movq "DCTSIZE_S"*3*2+"DCTSIZE_S"(%%"REG_S"), %%mm6 \n\t" - "punpckhwd %%mm2, %%mm4 \n\t" - - "movq %%mm5, %%mm2 \n\t" - "punpcklwd %%mm6, %%mm5 \n\t" - - "psubw %%mm0, %%mm7 \n\t" //t2 - "punpckhwd %%mm6, %%mm2 \n\t" - - "movq %%mm3, %%mm0 \n\t" - "punpckldq %%mm5, %%mm3 \n\t" //4 - - "punpckhdq %%mm5, %%mm0 \n\t" //5 - "movq %%mm4, %%mm5 \n\t" - - // - "movq %%mm3, %%mm6 \n\t" - "punpckldq %%mm2, %%mm4 \n\t" //6 - - "psubw %%mm0, %%mm3 \n\t" //z10 - "punpckhdq %%mm2, %%mm5 \n\t" //7 - - "paddw %%mm0, %%mm6 \n\t" //z13 - "movq %%mm4, %%mm2 \n\t" - - "movq %%mm3, %%mm0 \n\t" - "psubw %%mm5, %%mm4 \n\t" //z12 - - "pmulhw "MANGLE(MM_FIX_2_613125930)", %%mm0 \n\t" //- - "paddw %%mm4, %%mm3 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_847759065)", %%mm3 \n\t" //z5 - "paddw %%mm5, %%mm2 \n\t" //z11 > - - "pmulhw "MANGLE(MM_FIX_1_082392200)", %%mm4 \n\t" - "movq %%mm2, %%mm5 \n\t" - - "psubw %%mm6, %%mm2 \n\t" - "paddw %%mm6, %%mm5 \n\t" //t7 - - "pmulhw "MANGLE(MM_FIX_1_414213562)", %%mm2 \n\t" //t11 - "paddw %%mm3, %%mm0 \n\t" //t12 - - "psllw $3, %%mm0 \n\t" - "psubw %%mm3, %%mm4 \n\t" //t10 - - "movq 0*8+%3, %%mm6 \n\t" - "movq %%mm1, %%mm3 \n\t" - - "psllw $3, %%mm4 \n\t" - "psubw %%mm5, %%mm0 \n\t" //t6 - - "psllw $3, %%mm2 \n\t" - "paddw %%mm0, %%mm1 \n\t" //d1 - - "psubw %%mm0, %%mm2 \n\t" //t5 - "psubw %%mm0, %%mm3 \n\t" //d6 - - "paddw %%mm2, %%mm4 \n\t" //t4 - "movq %%mm7, %%mm0 \n\t" - - "paddw %%mm2, %%mm7 \n\t" //d2 - "psubw %%mm2, %%mm0 \n\t" //d5 - - "movq "MANGLE(MM_DESCALE_RND)", %%mm2 \n\t" //4 - "psubw %%mm5, %%mm6 \n\t" //d7 - - "paddw 0*8+%3, %%mm5 \n\t" //d0 - "paddw %%mm2, %%mm1 \n\t" - - "paddw %%mm2, %%mm5 \n\t" - "psraw $3, %%mm1 \n\t" - - "paddw %%mm2, %%mm7 \n\t" - "psraw $3, %%mm5 \n\t" - - "paddw (%%"REG_D"), %%mm5 \n\t" - "psraw $3, %%mm7 \n\t" - - "paddw (%%"REG_D",%%"REG_a",), %%mm1 \n\t" - "paddw %%mm2, %%mm0 \n\t" - - "paddw (%%"REG_D",%%"REG_a",2), %%mm7 \n\t" - "paddw %%mm2, %%mm3 \n\t" - - "movq %%mm5, (%%"REG_D") \n\t" - "paddw %%mm2, %%mm6 \n\t" - - "movq %%mm1, (%%"REG_D",%%"REG_a",) \n\t" - "psraw $3, %%mm0 \n\t" - - "movq %%mm7, (%%"REG_D",%%"REG_a",2) \n\t" - "add %%"REG_d", %%"REG_D" \n\t" //3*ls - - "movq 1*8+%3, %%mm5 \n\t" //t3 - "psraw $3, %%mm3 \n\t" - - "paddw (%%"REG_D",%%"REG_a",2), %%mm0 \n\t" - "psubw %%mm4, %%mm5 \n\t" //d3 - - "paddw (%%"REG_D",%%"REG_d",), %%mm3 \n\t" - "psraw $3, %%mm6 \n\t" - - "paddw 1*8+%3, %%mm4 \n\t" //d4 - "paddw %%mm2, %%mm5 \n\t" - - "paddw (%%"REG_D",%%"REG_a",4), %%mm6 \n\t" - "paddw %%mm2, %%mm4 \n\t" - - "movq %%mm0, (%%"REG_D",%%"REG_a",2) \n\t" - "psraw $3, %%mm5 \n\t" - - "paddw (%%"REG_D"), %%mm5 \n\t" - "psraw $3, %%mm4 \n\t" - - "paddw (%%"REG_D",%%"REG_a",), %%mm4 \n\t" - "add $"DCTSIZE_S"*2*4, %%"REG_S" \n\t" //4 rows - - "movq %%mm3, (%%"REG_D",%%"REG_d",) \n\t" - "movq %%mm6, (%%"REG_D",%%"REG_a",4) \n\t" - "movq %%mm5, (%%"REG_D") \n\t" - "movq %%mm4, (%%"REG_D",%%"REG_a",) \n\t" - - "sub %%"REG_d", %%"REG_D" \n\t" - "add $8, %%"REG_D" \n\t" - "dec %%"REG_c" \n\t" - "jnz 1b \n\t" - - : "+S"(workspace), "+D"(output_adr), "+c"(cnt), "=o"(temps) - : "a"(output_stride*sizeof(short)) - : "%"REG_d - ); -} - -#endif // HAVE_MMX - -#if !HAVE_MMX - -static void row_fdct_c(DCTELEM *data, const uint8_t *pixels, int line_size, int cnt) -{ - int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_simd16_t tmp10, tmp11, tmp12, tmp13; - int_simd16_t z1, z2, z3, z4, z5, z11, z13; - DCTELEM *dataptr; - - cnt*=4; - // Pass 1: process rows. - - dataptr = data; - for (; cnt > 0; cnt--) { - tmp0 = pixels[line_size*0] + pixels[line_size*7]; - tmp7 = pixels[line_size*0] - pixels[line_size*7]; - tmp1 = pixels[line_size*1] + pixels[line_size*6]; - tmp6 = pixels[line_size*1] - pixels[line_size*6]; - tmp2 = pixels[line_size*2] + pixels[line_size*5]; - tmp5 = pixels[line_size*2] - pixels[line_size*5]; - tmp3 = pixels[line_size*3] + pixels[line_size*4]; - tmp4 = pixels[line_size*3] - pixels[line_size*4]; - - // Even part - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - //Even columns are written first, this leads to different order of columns - //in column_fidct(), but they are processed independently, so all ok. - //Later in the row_idct() columns readed at the same order. - dataptr[2] = tmp10 + tmp11; - dataptr[3] = tmp10 - tmp11; - - z1 = MULTIPLY16H((tmp12 + tmp13)<<2, FIX_0_707106781); - dataptr[0] = tmp13 + z1; - dataptr[1] = tmp13 - z1; - - // Odd part - - tmp10 = (tmp4 + tmp5) <<2; - tmp11 = (tmp5 + tmp6) <<2; - tmp12 = (tmp6 + tmp7) <<2; - - z5 = MULTIPLY16H(tmp10 - tmp12, FIX_0_382683433); - z2 = MULTIPLY16H(tmp10, FIX_0_541196100) + z5; - z4 = MULTIPLY16H(tmp12, FIX_1_306562965) + z5; - z3 = MULTIPLY16H(tmp11, FIX_0_707106781); - - z11 = tmp7 + z3; - z13 = tmp7 - z3; - - dataptr[4] = z13 + z2; - dataptr[5] = z13 - z2; - dataptr[6] = z11 + z4; - dataptr[7] = z11 - z4; - - pixels++; // advance pointer to next column - dataptr += DCTSIZE; - } -} - -#else /* HAVE_MMX */ - -static void row_fdct_mmx(DCTELEM *data, const uint8_t *pixels, int line_size, int cnt) -{ - uint64_t __attribute__((aligned(8))) temps[4]; - __asm__ volatile( - "lea (%%"REG_a",%%"REG_a",2), %%"REG_d" \n\t" - "6: \n\t" - "movd (%%"REG_S"), %%mm0 \n\t" - "pxor %%mm7, %%mm7 \n\t" - - "movd (%%"REG_S",%%"REG_a",), %%mm1 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - - "movd (%%"REG_S",%%"REG_a",2), %%mm2 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - - "punpcklbw %%mm7, %%mm2 \n\t" - "add %%"REG_d", %%"REG_S" \n\t" - - "movq %%mm0, %%mm5 \n\t" - // - - "movd (%%"REG_S",%%"REG_a",4), %%mm3 \n\t" //7 ;prefetch! - "movq %%mm1, %%mm6 \n\t" - - "movd (%%"REG_S",%%"REG_d",), %%mm4 \n\t" //6 - "punpcklbw %%mm7, %%mm3 \n\t" - - "psubw %%mm3, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - - "paddw %%mm3, %%mm0 \n\t" - "psubw %%mm4, %%mm6 \n\t" - - "movd (%%"REG_S",%%"REG_a",2), %%mm3 \n\t" //5 - "paddw %%mm4, %%mm1 \n\t" - - "movq %%mm5, 0*8+%3 \n\t" //t7 - "punpcklbw %%mm7, %%mm3 \n\t" - - "movq %%mm6, 1*8+%3 \n\t" //t6 - "movq %%mm2, %%mm4 \n\t" - - "movd (%%"REG_S"), %%mm5 \n\t" //3 - "paddw %%mm3, %%mm2 \n\t" - - "movd (%%"REG_S",%%"REG_a",), %%mm6 \n\t" //4 - "punpcklbw %%mm7, %%mm5 \n\t" - - "psubw %%mm3, %%mm4 \n\t" - "punpcklbw %%mm7, %%mm6 \n\t" - - "movq %%mm5, %%mm3 \n\t" - "paddw %%mm6, %%mm5 \n\t" //t3 - - "psubw %%mm6, %%mm3 \n\t" //t4 ; t0 t1 t2 t4 t5 t3 - - - "movq %%mm0, %%mm6 \n\t" - - "movq %%mm1, %%mm7 \n\t" - "psubw %%mm5, %%mm0 \n\t" //t13 - - "psubw %%mm2, %%mm1 \n\t" - "paddw %%mm2, %%mm7 \n\t" //t11 - - "paddw %%mm0, %%mm1 \n\t" - "movq %%mm7, %%mm2 \n\t" - - "psllw $2, %%mm1 \n\t" - "paddw %%mm5, %%mm6 \n\t" //t10 - - "pmulhw "MANGLE(MM_FIX_0_707106781)", %%mm1 \n\t" - "paddw %%mm6, %%mm7 \n\t" //d2 - - "psubw %%mm2, %%mm6 \n\t" //d3 - "movq %%mm0, %%mm5 \n\t" - - //transpose 4x4 - "movq %%mm7, %%mm2 \n\t" - "punpcklwd %%mm6, %%mm7 \n\t" - - "paddw %%mm1, %%mm0 \n\t" //d0 - "punpckhwd %%mm6, %%mm2 \n\t" - - "psubw %%mm1, %%mm5 \n\t" //d1 - "movq %%mm0, %%mm6 \n\t" - - "movq 1*8+%3, %%mm1 \n\t" - "punpcklwd %%mm5, %%mm0 \n\t" - - "punpckhwd %%mm5, %%mm6 \n\t" - "movq %%mm0, %%mm5 \n\t" - - "punpckldq %%mm7, %%mm0 \n\t" //0 - "paddw %%mm4, %%mm3 \n\t" - - "punpckhdq %%mm7, %%mm5 \n\t" //1 - "movq %%mm6, %%mm7 \n\t" - - "movq %%mm0, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "punpckldq %%mm2, %%mm6 \n\t" //2 - - "movq %%mm5, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "punpckhdq %%mm2, %%mm7 \n\t" //3 - - "movq %%mm6, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "paddw %%mm1, %%mm4 \n\t" - - "movq %%mm7, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - "psllw $2, %%mm3 \n\t" //t10 - - "movq 0*8+%3, %%mm2 \n\t" - "psllw $2, %%mm4 \n\t" //t11 - - "pmulhw "MANGLE(MM_FIX_0_707106781)", %%mm4 \n\t" //z3 - "paddw %%mm2, %%mm1 \n\t" - - "psllw $2, %%mm1 \n\t" //t12 - "movq %%mm3, %%mm0 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_541196100)", %%mm0 \n\t" - "psubw %%mm1, %%mm3 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_382683433)", %%mm3 \n\t" //z5 - "movq %%mm2, %%mm5 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_306562965)", %%mm1 \n\t" - "psubw %%mm4, %%mm2 \n\t" //z13 - - "paddw %%mm4, %%mm5 \n\t" //z11 - "movq %%mm2, %%mm6 \n\t" - - "paddw %%mm3, %%mm0 \n\t" //z2 - "movq %%mm5, %%mm7 \n\t" - - "paddw %%mm0, %%mm2 \n\t" //d4 - "psubw %%mm0, %%mm6 \n\t" //d5 - - "movq %%mm2, %%mm4 \n\t" - "paddw %%mm3, %%mm1 \n\t" //z4 - - //transpose 4x4 - "punpcklwd %%mm6, %%mm2 \n\t" - "paddw %%mm1, %%mm5 \n\t" //d6 - - "punpckhwd %%mm6, %%mm4 \n\t" - "psubw %%mm1, %%mm7 \n\t" //d7 - - "movq %%mm5, %%mm6 \n\t" - "punpcklwd %%mm7, %%mm5 \n\t" - - "punpckhwd %%mm7, %%mm6 \n\t" - "movq %%mm2, %%mm7 \n\t" - - "punpckldq %%mm5, %%mm2 \n\t" //4 - "sub %%"REG_d", %%"REG_S" \n\t" - - "punpckhdq %%mm5, %%mm7 \n\t" //5 - "movq %%mm4, %%mm5 \n\t" - - "movq %%mm2, "DCTSIZE_S"*0*2+"DCTSIZE_S"(%%"REG_D") \n\t" - "punpckldq %%mm6, %%mm4 \n\t" //6 - - "movq %%mm7, "DCTSIZE_S"*1*2+"DCTSIZE_S"(%%"REG_D") \n\t" - "punpckhdq %%mm6, %%mm5 \n\t" //7 - - "movq %%mm4, "DCTSIZE_S"*2*2+"DCTSIZE_S"(%%"REG_D") \n\t" - "add $4, %%"REG_S" \n\t" - - "movq %%mm5, "DCTSIZE_S"*3*2+"DCTSIZE_S"(%%"REG_D") \n\t" - "add $"DCTSIZE_S"*2*4, %%"REG_D" \n\t" //4 rows - "dec %%"REG_c" \n\t" - "jnz 6b \n\t" - - : "+S"(pixels), "+D"(data), "+c"(cnt), "=o"(temps) - : "a"(line_size) - : "%"REG_d); -} - -#endif // HAVE_MMX diff --git a/libmpcodecs/vf_geq.c b/libmpcodecs/vf_geq.c deleted file mode 100644 index 5c2e6c32c7..0000000000 --- a/libmpcodecs/vf_geq.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2006 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include - -#include -#include - -#include "config.h" - -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - AVExpr * e[3]; - int framenum; - mp_image_t *mpi; -}; - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static inline double getpix(struct vf_instance *vf, double x, double y, int plane){ - int xi, yi; - mp_image_t *mpi= vf->priv->mpi; - int stride= mpi->stride[plane]; - uint8_t *src= mpi->planes[plane]; - xi=x= FFMIN(FFMAX(x, 0), (mpi->w >> (plane ? mpi->chroma_x_shift : 0))-1); - yi=y= FFMIN(FFMAX(y, 0), (mpi->h >> (plane ? mpi->chroma_y_shift : 0))-1); - - x-=xi; - y-=yi; - - return - (1-y)*((1-x)*src[xi + yi * stride] + x*src[xi + 1 + yi * stride]) - + y *((1-x)*src[xi + (yi+1) * stride] + x*src[xi + 1 + (yi+1) * stride]); -} - -//FIXME cubic interpolate -//FIXME keep the last few frames -static double lum(void *vf, double x, double y){ - return getpix(vf, x, y, 0); -} - -static double cb(void *vf, double x, double y){ - return getpix(vf, x, y, 1); -} - -static double cr(void *vf, double x, double y){ - return getpix(vf, x, y, 2); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - int x,y, plane; - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // no DR, so get a new image! hope we'll get DR buffer: - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->w,mpi->h); - } - - dmpi= vf->dmpi; - vf->priv->mpi= mpi; - - vf_clone_mpi_attributes(dmpi, mpi); - - for(plane=0; plane<3; plane++){ - int w= mpi->w >> (plane ? mpi->chroma_x_shift : 0); - int h= mpi->h >> (plane ? mpi->chroma_y_shift : 0); - uint8_t *dst = dmpi->planes[plane]; - int dst_stride= dmpi->stride[plane]; - double const_values[]={ - M_PI, - M_E, - 0, - 0, - w, - h, - vf->priv->framenum, - w/(double)mpi->w, - h/(double)mpi->h, - 0 - }; - if (!vf->priv->e[plane]) continue; - for(y=0; ypriv->e[plane], - const_values, vf); - } - } - } - - vf->priv->framenum++; - - return vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf){ - av_free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// -static int vf_open(vf_instance_t *vf, char *args){ - char eq[3][2000] = { { 0 }, { 0 }, { 0 } }; - int plane, res; - - vf->config=config; - vf->put_image=put_image; -// vf->get_image=get_image; - vf->uninit=uninit; - vf->priv=av_malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - if (args) sscanf(args, "%1999[^:]:%1999[^:]:%1999[^:]", eq[0], eq[1], eq[2]); - - if (!eq[1][0]) strncpy(eq[1], eq[0], sizeof(eq[0])-1); - if (!eq[2][0]) strncpy(eq[2], eq[1], sizeof(eq[0])-1); - - for(plane=0; plane<3; plane++){ - const char * const const_names[]={ - "PI", - "E", - "X", - "Y", - "W", - "H", - "N", - "SW", - "SH", - NULL - }; - const char * const func2_names[]={ - "lum", - "cb", - "cr", - "p", - NULL - }; - double (*func2[])(void *, double, double)={ - lum, - cb, - cr, - plane==0 ? lum : (plane==1 ? cb : cr), - NULL - }; - res = av_expr_parse(&vf->priv->e[plane], eq[plane], const_names, NULL, NULL, func2_names, func2, 0, NULL); - - if (res < 0) { - mp_msg(MSGT_VFILTER, MSGL_ERR, "geq: error loading equation `%s'\n", eq[plane]); - return 0; - } - } - - return 1; -} - -const vf_info_t vf_info_geq = { - "generic equation filter", - "geq", - "Michael Niedermayer", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_halfpack.c b/libmpcodecs/vf_halfpack.c deleted file mode 100644 index b67f8237b2..0000000000 --- a/libmpcodecs/vf_halfpack.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "vf_scale.h" - -#include "libswscale/swscale.h" -#include "fmt-conversion.h" - -struct vf_priv_s { - int field; - struct SwsContext *ctx; -}; - -#if HAVE_MMX -static void halfpack_MMX(unsigned char *dst, unsigned char *src[3], - int dststride, int srcstride[3], - int w, int h) -{ - int j; - unsigned char *y1, *y2, *u, *v; - int dstinc, yinc, uinc, vinc; - - y1 = src[0]; - y2 = src[0] + srcstride[0]; - u = src[1]; - v = src[2]; - - dstinc = dststride - 2*w; - yinc = 2*srcstride[0] - w; - uinc = srcstride[1] - w/2; - vinc = srcstride[2] - w/2; - - for (h/=2; h; h--) { - __asm__ ( - "pxor %%mm0, %%mm0 \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%0), %%mm1 \n\t" - "movq (%0), %%mm2 \n\t" - "movq (%1), %%mm3 \n\t" - "movq (%1), %%mm4 \n\t" - "punpcklbw %%mm0, %%mm1 \n\t" - "punpckhbw %%mm0, %%mm2 \n\t" - "punpcklbw %%mm0, %%mm3 \n\t" - "punpckhbw %%mm0, %%mm4 \n\t" - "paddw %%mm3, %%mm1 \n\t" - "paddw %%mm4, %%mm2 \n\t" - "psrlw $1, %%mm1 \n\t" - "psrlw $1, %%mm2 \n\t" - - "movq (%2), %%mm3 \n\t" - "movq (%3), %%mm5 \n\t" - "punpcklbw %%mm0, %%mm3 \n\t" - "punpcklbw %%mm0, %%mm5 \n\t" - "movq %%mm3, %%mm4 \n\t" - "movq %%mm5, %%mm6 \n\t" - "punpcklwd %%mm0, %%mm3 \n\t" - "punpckhwd %%mm0, %%mm4 \n\t" - "punpcklwd %%mm0, %%mm5 \n\t" - "punpckhwd %%mm0, %%mm6 \n\t" - "pslld $8, %%mm3 \n\t" - "pslld $8, %%mm4 \n\t" - "pslld $24, %%mm5 \n\t" - "pslld $24, %%mm6 \n\t" - - "por %%mm3, %%mm1 \n\t" - "por %%mm4, %%mm2 \n\t" - "por %%mm5, %%mm1 \n\t" - "por %%mm6, %%mm2 \n\t" - - "add $8, %0 \n\t" - "add $8, %1 \n\t" - "add $4, %2 \n\t" - "add $4, %3 \n\t" - "movq %%mm1, (%8) \n\t" - "movq %%mm2, 8(%8) \n\t" - "add $16, %8 \n\t" - "decl %9 \n\t" - "jnz 1b \n\t" - : "=r" (y1), "=r" (y2), "=r" (u), "=r" (v) - : "0" (y1), "1" (y2), "2" (u), "3" (v), "r" (dst), "r" (w/8) - : "memory" - ); - for (j = (w&7)/2; j; j--) { - *dst++ = (*y1++ + *y2++)/2; - *dst++ = *u++; - *dst++ = (*y1++ + *y2++)/2; - *dst++ = *v++; - } - y1 += yinc; - y2 += yinc; - u += uinc; - v += vinc; - dst += dstinc; - } - __asm__ volatile ( "emms \n\t" ::: "memory" ); -} -#endif - - - -static void halfpack_C(unsigned char *dst, unsigned char *src[3], - int dststride, int srcstride[3], - int w, int h) -{ - int i, j; - unsigned char *y1, *y2, *u, *v; - int dstinc, yinc, uinc, vinc; - - y1 = src[0]; - y2 = src[0] + srcstride[0]; - u = src[1]; - v = src[2]; - - dstinc = dststride - 2*w; - yinc = 2*srcstride[0] - w; - uinc = srcstride[1] - w/2; - vinc = srcstride[2] - w/2; - - for (i = h/2; i; i--) { - for (j = w/2; j; j--) { - *dst++ = (*y1++ + *y2++)>>1; - *dst++ = *u++; - *dst++ = (*y1++ + *y2++)>>1; - *dst++ = *v++; - } - y1 += yinc; - y2 += yinc; - u += uinc; - v += vinc; - dst += dstinc; - } -} - -static void (*halfpack)(unsigned char *dst, unsigned char *src[3], - int dststride, int srcstride[3], int w, int h); - - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - const uint8_t *src[MP_MAX_PLANES] = { - mpi->planes[0] + mpi->stride[0]*vf->priv->field, - mpi->planes[1], mpi->planes[2], NULL}; - int src_stride[MP_MAX_PLANES] = {mpi->stride[0]*2, mpi->stride[1], mpi->stride[2], 0}; - mp_image_t *dmpi; - - // hope we'll get DR buffer: - dmpi=vf_get_image(vf->next, IMGFMT_YUY2, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w, mpi->h/2); - - switch(vf->priv->field) { - case 0: - case 1: - sws_scale(vf->priv->ctx, src, src_stride, - 0, mpi->h/2, dmpi->planes, dmpi->stride); - break; - default: - halfpack(dmpi->planes[0], mpi->planes, dmpi->stride[0], - mpi->stride, mpi->w, mpi->h); - } - - return vf_next_put_image(vf,dmpi, pts); -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - if (vf->priv->field < 2) { - sws_freeContext(vf->priv->ctx); - // get unscaled 422p -> yuy2 conversion - vf->priv->ctx = - sws_getContext(width, height / 2, PIX_FMT_YUV422P, - width, height / 2, PIX_FMT_YUYV422, - SWS_POINT | SWS_PRINT_INFO, - NULL, NULL, NULL); - } - /* FIXME - also support UYVY output? */ - return vf_next_config(vf, width, height/2, d_width, d_height, flags, IMGFMT_YUY2); -} - - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - /* FIXME - really any YUV 4:2:0 input format should work */ - switch (fmt) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - return vf_next_query_format(vf,IMGFMT_YUY2); - } - return 0; -} - -static void uninit(struct vf_instance *vf) -{ - sws_freeContext(vf->priv->ctx); - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - vf->config=config; - vf->query_format=query_format; - vf->put_image=put_image; - vf->uninit=uninit; - - vf->priv = calloc(1, sizeof (struct vf_priv_s)); - vf->priv->field = 2; - if (args) sscanf(args, "%d", &vf->priv->field); - - halfpack = halfpack_C; -#if HAVE_MMX - if(gCpuCaps.hasMMX) halfpack = halfpack_MMX; -#endif - return 1; -} - -const vf_info_t vf_info_halfpack = { - "yuv planar 4:2:0 -> packed 4:2:2, half height", - "halfpack", - "Richard Felker", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_harddup.c b/libmpcodecs/vf_harddup.c deleted file mode 100644 index b2b1bd6483..0000000000 --- a/libmpcodecs/vf_harddup.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - mp_image_t *last_mpi; -}; - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - - vf->priv->last_mpi = mpi; - - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_EXPORT, 0, mpi->width, mpi->height); - - dmpi->planes[0] = mpi->planes[0]; - dmpi->stride[0] = mpi->stride[0]; - if (dmpi->flags&MP_IMGFLAG_PLANAR) { - dmpi->planes[1] = mpi->planes[1]; - dmpi->stride[1] = mpi->stride[1]; - dmpi->planes[2] = mpi->planes[2]; - dmpi->stride[2] = mpi->stride[2]; - } - - return vf_next_put_image(vf, dmpi, pts); -} - -static int control(struct vf_instance *vf, int request, void* data) -{ - switch (request) { - case VFCTRL_DUPLICATE_FRAME: - if (!vf->priv->last_mpi) break; - // This is a huge hack. We assume nothing - // has been called earlier in the filter chain - // since the last put_image. This is reasonable - // because we're handling a duplicate frame! - if (put_image(vf, vf->priv->last_mpi, MP_NOPTS_VALUE)) - return CONTROL_TRUE; - break; - } - return vf_next_control(vf, request, data); -} - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - vf->put_image = put_image; - vf->control = control; - vf->uninit = uninit; - vf->priv = calloc(1, sizeof(struct vf_priv_s)); - return 1; -} - -const vf_info_t vf_info_harddup = { - "resubmit duplicate frames for encoding", - "harddup", - "Rich Felker", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_hue.c b/libmpcodecs/vf_hue.c deleted file mode 100644 index 47fe19ac57..0000000000 --- a/libmpcodecs/vf_hue.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/video_out.h" - -#include "m_option.h" -#include "m_struct.h" - -static struct vf_priv_s { - uint8_t *buf[2]; - float hue; - float saturation; -} const vf_priv_dflt = { - {NULL, NULL}, - 0.0, - 1.0, -}; - -static void process_C(uint8_t *udst, uint8_t *vdst, uint8_t *usrc, uint8_t *vsrc, int dststride, int srcstride, - int w, int h, float hue, float sat) -{ - int i; - const int s= rint(sin(hue) * (1<<16) * sat); - const int c= rint(cos(hue) * (1<<16) * sat); - - while (h--) { - for (i = 0; i>16; - int new_v= (s*u + c*v + (1<<15) + (128<<16))>>16; - if(new_u & 768) new_u= (-new_u)>>31; - if(new_v & 768) new_v= (-new_v)>>31; - udst[i]= new_u; - vdst[i]= new_v; - } - usrc += srcstride; - vsrc += srcstride; - udst += dststride; - vdst += dststride; - } -} - -static void (*process)(uint8_t *udst, uint8_t *vdst, uint8_t *usrc, uint8_t *vsrc, int dststride, int srcstride, - int w, int h, float hue, float sat); - -/* FIXME: add packed yuv version of process */ - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - - dmpi=vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_EXPORT, 0, - mpi->w, mpi->h); - - dmpi->planes[0] = mpi->planes[0]; - dmpi->stride[0] = mpi->stride[0]; - dmpi->stride[1] = mpi->stride[1]; - dmpi->stride[2] = mpi->stride[2]; - - if (!vf->priv->buf[0]){ - vf->priv->buf[0] = malloc(mpi->stride[1]*mpi->h >> mpi->chroma_y_shift); - vf->priv->buf[1] = malloc(mpi->stride[2]*mpi->h >> mpi->chroma_y_shift); - } - - if (vf->priv->hue == 0 && vf->priv->saturation == 1){ - dmpi->planes[1] = mpi->planes[1]; - dmpi->planes[2] = mpi->planes[2]; - }else { - dmpi->planes[1] = vf->priv->buf[0]; - dmpi->planes[2] = vf->priv->buf[1]; - process(dmpi->planes[1], dmpi->planes[2], - mpi->planes[1], mpi->planes[2], - dmpi->stride[1],mpi->stride[1], - mpi->w>> mpi->chroma_x_shift, mpi->h>> mpi->chroma_y_shift, - vf->priv->hue, vf->priv->saturation); - } - - return vf_next_put_image(vf,dmpi, pts); -} - -static int control(struct vf_instance *vf, int request, void* data) -{ - vf_equalizer_t *eq; - - switch (request) { - case VFCTRL_SET_EQUALIZER: - eq = data; - if (!strcmp(eq->item,"hue")) { - vf->priv->hue = eq->value * M_PI / 100; - return CONTROL_TRUE; - } else if (!strcmp(eq->item,"saturation")) { - vf->priv->saturation = (eq->value + 100)/100.0; - return CONTROL_TRUE; - } - break; - case VFCTRL_GET_EQUALIZER: - eq = data; - if (!strcmp(eq->item,"hue")) { - eq->value = rint(vf->priv->hue *100 / M_PI); - return CONTROL_TRUE; - }else if (!strcmp(eq->item,"saturation")) { - eq->value = rint(vf->priv->saturation*100 - 100); - return CONTROL_TRUE; - } - break; - } - return vf_next_control(vf, request, data); -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - switch (fmt) { - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv->buf[0]); - free(vf->priv->buf[1]); - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - vf->control=control; - vf->query_format=query_format; - vf->put_image=put_image; - vf->uninit=uninit; - - vf->priv->hue *= M_PI / 180.0; - - process = process_C; - return 1; -} - -#define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f) -static const m_option_t vf_opts_fields[] = { - {"hue", ST_OFF(hue), CONF_TYPE_FLOAT, M_OPT_RANGE,-180.0 ,180.0, NULL}, - {"saturation", ST_OFF(saturation), CONF_TYPE_FLOAT, M_OPT_RANGE,-10.0 ,10.0, NULL}, - { NULL, NULL, 0, 0, 0, 0, NULL } -}; - -static const m_struct_t vf_opts = { - "hue", - sizeof(struct vf_priv_s), - &vf_priv_dflt, - vf_opts_fields -}; - -const vf_info_t vf_info_hue = { - "hue changer", - "hue", - "Michael Niedermayer", - "", - vf_open, - &vf_opts -}; diff --git a/libmpcodecs/vf_il.c b/libmpcodecs/vf_il.c deleted file mode 100644 index f209197376..0000000000 --- a/libmpcodecs/vf_il.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2002 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include - -#include "mp_msg.h" -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libvo/fastmemcpy.h" - - -//===========================================================================// - -typedef struct FilterParam{ - int interleave; - int swap; -}FilterParam; - -struct vf_priv_s { - FilterParam lumaParam; - FilterParam chromaParam; -}; - -/***************************************************************************/ - -static void interleave(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, int interleave, int swap){ - const int a= swap; - const int b= 1-a; - const int m= h>>1; - int y; - - switch(interleave){ - case -1: - for(y=0; y < m; y++){ - fast_memcpy(dst + dstStride* y , src + srcStride*(y*2 + a), w); - fast_memcpy(dst + dstStride*(y + m), src + srcStride*(y*2 + b), w); - } - break; - case 0: - for(y=0; y < m; y++){ - fast_memcpy(dst + dstStride* y*2 , src + srcStride*(y*2 + a), w); - fast_memcpy(dst + dstStride*(y*2+1), src + srcStride*(y*2 + b), w); - } - break; - case 1: - for(y=0; y < m; y++){ - fast_memcpy(dst + dstStride*(y*2+a), src + srcStride* y , w); - fast_memcpy(dst + dstStride*(y*2+b), src + srcStride*(y + m), w); - } - break; - } -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - int w; - FilterParam *luma = &vf->priv->lumaParam; - FilterParam *chroma= &vf->priv->chromaParam; - - mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w,mpi->h); - - if(mpi->flags&MP_IMGFLAG_PLANAR) - w= mpi->w; - else - w= mpi->w * mpi->bpp/8; - - interleave(dmpi->planes[0], mpi->planes[0], - w, mpi->h, dmpi->stride[0], mpi->stride[0], luma->interleave, luma->swap); - - if(mpi->flags&MP_IMGFLAG_PLANAR){ - int cw= mpi->w >> mpi->chroma_x_shift; - int ch= mpi->h >> mpi->chroma_y_shift; - - interleave(dmpi->planes[1], mpi->planes[1], cw,ch, - dmpi->stride[1], mpi->stride[1], chroma->interleave, luma->swap); - interleave(dmpi->planes[2], mpi->planes[2], cw,ch, - dmpi->stride[2], mpi->stride[2], chroma->interleave, luma->swap); - } - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static void parse(FilterParam *fp, char* args){ - char *pos; - char *max= strchr(args, ':'); - - if(!max) max= args + strlen(args); - - pos= strchr(args, 's'); - if(pos && posswap=1; - pos= strchr(args, 'i'); - if(pos && posinterleave=1; - pos= strchr(args, 'd'); - if(pos && posinterleave=-1; -} - -static int vf_open(vf_instance_t *vf, char *args){ - - vf->put_image=put_image; -// vf->get_image=get_image; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - if(args) - { - char *arg2= strchr(args,':'); - if(arg2) parse(&vf->priv->chromaParam, arg2+1); - parse(&vf->priv->lumaParam, args); - } - - return 1; -} - -const vf_info_t vf_info_il = { - "(de)interleave", - "il", - "Michael Niedermayer", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_ivtc.c b/libmpcodecs/vf_ivtc.c deleted file mode 100644 index 966292ff14..0000000000 --- a/libmpcodecs/vf_ivtc.c +++ /dev/null @@ -1,555 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/fastmemcpy.h" - - -struct metrics { - /* difference: total, even lines, odd lines */ - int d, e, o; - /* noise: temporal, spacial (current), spacial (past) */ - int t, s, p; -}; - -struct frameinfo { - /* peak, relative, mean */ - struct metrics p, r, m; -}; - -struct vf_priv_s { - struct frameinfo fi[2]; - mp_image_t *dmpi; - int first; - int drop, lastdrop, dropnext; - int inframes, outframes; - struct vf_detc_pts_buf ptsbuf; -}; - -enum { - F_DROP, - F_MERGE, - F_NEXT, - F_SHOW -}; - -#if HAVE_MMX && HAVE_EBX_AVAILABLE -static void block_diffs_MMX(struct metrics *m, unsigned char *old, unsigned char *new, int os, int ns) -{ - int i; - short out[24]; // output buffer for the partial metrics from the mmx code - - __asm__ ( - "movl $4, %%ecx \n\t" - "pxor %%mm4, %%mm4 \n\t" // 4 even difference sums - "pxor %%mm5, %%mm5 \n\t" // 4 odd difference sums - "pxor %%mm7, %%mm7 \n\t" // all zeros - - ASMALIGN(4) - "1: \n\t" - - // Even difference - "movq (%%"REG_S"), %%mm0 \n\t" - "movq (%%"REG_S"), %%mm2 \n\t" - "add %%"REG_a", %%"REG_S" \n\t" - "movq (%%"REG_D"), %%mm1 \n\t" - "add %%"REG_b", %%"REG_D" \n\t" - "psubusb %%mm1, %%mm2 \n\t" - "psubusb %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm0 \n\t" - "movq %%mm1, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddw %%mm0, %%mm4 \n\t" - "paddw %%mm1, %%mm4 \n\t" - "paddw %%mm2, %%mm4 \n\t" - "paddw %%mm3, %%mm4 \n\t" - - // Odd difference - "movq (%%"REG_S"), %%mm0 \n\t" - "movq (%%"REG_S"), %%mm2 \n\t" - "add %%"REG_a", %%"REG_S" \n\t" - "movq (%%"REG_D"), %%mm1 \n\t" - "add %%"REG_b", %%"REG_D" \n\t" - "psubusb %%mm1, %%mm2 \n\t" - "psubusb %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm0 \n\t" - "movq %%mm1, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddw %%mm0, %%mm5 \n\t" - "paddw %%mm1, %%mm5 \n\t" - "paddw %%mm2, %%mm5 \n\t" - "paddw %%mm3, %%mm5 \n\t" - - "decl %%ecx \n\t" - "jnz 1b \n\t" - "movq %%mm4, (%%"REG_d") \n\t" - "movq %%mm5, 8(%%"REG_d") \n\t" - : - : "S" (old), "D" (new), "a" (os), "b" (ns), "d" (out) - : "memory" - ); - m->e = out[0]+out[1]+out[2]+out[3]; - m->o = out[4]+out[5]+out[6]+out[7]; - m->d = m->e + m->o; - - __asm__ ( - // First loop to measure first four columns - "movl $4, %%ecx \n\t" - "pxor %%mm4, %%mm4 \n\t" // Past spacial noise - "pxor %%mm5, %%mm5 \n\t" // Temporal noise - "pxor %%mm6, %%mm6 \n\t" // Current spacial noise - - ASMALIGN(4) - "2: \n\t" - - "movq (%%"REG_S"), %%mm0 \n\t" - "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t" - "add %%"REG_a", %%"REG_S" \n\t" - "add %%"REG_a", %%"REG_S" \n\t" - "movq (%%"REG_D"), %%mm2 \n\t" - "movq (%%"REG_D",%%"REG_b"), %%mm3 \n\t" - "add %%"REG_b", %%"REG_D" \n\t" - "add %%"REG_b", %%"REG_D" \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpcklbw %%mm7, %%mm3 \n\t" - "paddw %%mm1, %%mm4 \n\t" - "paddw %%mm1, %%mm5 \n\t" - "paddw %%mm3, %%mm6 \n\t" - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm2, %%mm5 \n\t" - "psubw %%mm2, %%mm6 \n\t" - - "decl %%ecx \n\t" - "jnz 2b \n\t" - - "movq %%mm0, %%mm1 \n\t" - "movq %%mm0, %%mm2 \n\t" - "movq %%mm0, %%mm3 \n\t" - "pcmpgtw %%mm4, %%mm1 \n\t" - "pcmpgtw %%mm5, %%mm2 \n\t" - "pcmpgtw %%mm6, %%mm3 \n\t" - "pxor %%mm1, %%mm4 \n\t" - "pxor %%mm2, %%mm5 \n\t" - "pxor %%mm3, %%mm6 \n\t" - "psubw %%mm1, %%mm4 \n\t" - "psubw %%mm2, %%mm5 \n\t" - "psubw %%mm3, %%mm6 \n\t" - "movq %%mm4, (%%"REG_d") \n\t" - "movq %%mm5, 16(%%"REG_d") \n\t" - "movq %%mm6, 32(%%"REG_d") \n\t" - - "mov %%"REG_a", %%"REG_c" \n\t" - "shl $3, %%"REG_c" \n\t" - "sub %%"REG_c", %%"REG_S" \n\t" - "mov %%"REG_b", %%"REG_c" \n\t" - "shl $3, %%"REG_c" \n\t" - "sub %%"REG_c", %%"REG_D" \n\t" - - // Second loop for the last four columns - "movl $4, %%ecx \n\t" - "pxor %%mm4, %%mm4 \n\t" - "pxor %%mm5, %%mm5 \n\t" - "pxor %%mm6, %%mm6 \n\t" - - ASMALIGN(4) - "3: \n\t" - - "movq (%%"REG_S"), %%mm0 \n\t" - "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t" - "add %%"REG_a", %%"REG_S" \n\t" - "add %%"REG_a", %%"REG_S" \n\t" - "movq (%%"REG_D"), %%mm2 \n\t" - "movq (%%"REG_D",%%"REG_b"), %%mm3 \n\t" - "add %%"REG_b", %%"REG_D" \n\t" - "add %%"REG_b", %%"REG_D" \n\t" - "punpckhbw %%mm7, %%mm0 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddw %%mm1, %%mm4 \n\t" - "paddw %%mm1, %%mm5 \n\t" - "paddw %%mm3, %%mm6 \n\t" - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm2, %%mm5 \n\t" - "psubw %%mm2, %%mm6 \n\t" - - "decl %%ecx \n\t" - "jnz 3b \n\t" - - "movq %%mm0, %%mm1 \n\t" - "movq %%mm0, %%mm2 \n\t" - "movq %%mm0, %%mm3 \n\t" - "pcmpgtw %%mm4, %%mm1 \n\t" - "pcmpgtw %%mm5, %%mm2 \n\t" - "pcmpgtw %%mm6, %%mm3 \n\t" - "pxor %%mm1, %%mm4 \n\t" - "pxor %%mm2, %%mm5 \n\t" - "pxor %%mm3, %%mm6 \n\t" - "psubw %%mm1, %%mm4 \n\t" - "psubw %%mm2, %%mm5 \n\t" - "psubw %%mm3, %%mm6 \n\t" - "movq %%mm4, 8(%%"REG_d") \n\t" - "movq %%mm5, 24(%%"REG_d") \n\t" - "movq %%mm6, 40(%%"REG_d") \n\t" - - "emms \n\t" - : - : "S" (old), "D" (new), "a" ((long)os), "b" ((long)ns), "d" (out) - : "memory" - ); - m->p = m->t = m->s = 0; - for (i=0; i<8; i++) { - m->p += out[i]; - m->t += out[8+i]; - m->s += out[16+i]; - } - //printf("e=%d o=%d d=%d p=%d t=%d s=%d\n", m->e, m->o, m->d, m->p, m->t, m->s); -} -#endif - -//#define MAG(a) ((a)*(a)) -//#define MAG(a) (abs(a)) -#define MAG(a) (((a)^((a)>>31))-((a)>>31)) - -//#define LOWPASS(s) (((s)[-2] + 4*(s)[-1] + 6*(s)[0] + 4*(s)[1] + (s)[2])>>4) -//#define LOWPASS(s) (((s)[-1] + 2*(s)[0] + (s)[1])>>2) -#define LOWPASS(s) ((s)[0]) - - -static void block_diffs_C(struct metrics *m, unsigned char *old, unsigned char *new, int os, int ns) -{ - int x, y, e=0, o=0, s=0, p=0, t=0; - unsigned char *oldp, *newp; - m->s = m->p = m->t = 0; - for (x = 8; x; x--) { - oldp = old++; - newp = new++; - s = p = t = 0; - for (y = 4; y; y--) { - e += MAG(newp[0]-oldp[0]); - o += MAG(newp[ns]-oldp[os]); - s += newp[ns]-newp[0]; - p += oldp[os]-oldp[0]; - t += oldp[os]-newp[0]; - oldp += os<<1; - newp += ns<<1; - } - m->s += MAG(s); - m->p += MAG(p); - m->t += MAG(t); - } - m->e = e; - m->o = o; - m->d = e+o; -} - -static void (*block_diffs)(struct metrics *, unsigned char *, unsigned char *, int, int); - -#define MAXUP(a,b) ((a) = ((a)>(b)) ? (a) : (b)) - -static void diff_planes(struct frameinfo *fi, - unsigned char *old, unsigned char *new, int w, int h, int os, int ns) -{ - int x, y; - struct metrics l; - struct metrics *peak=&fi->p, *rel=&fi->r, *mean=&fi->m; - memset(peak, 0, sizeof(struct metrics)); - memset(rel, 0, sizeof(struct metrics)); - memset(mean, 0, sizeof(struct metrics)); - for (y = 0; y < h-7; y += 8) { - for (x = 8; x < w-8-7; x += 8) { - block_diffs(&l, old+x+y*os, new+x+y*ns, os, ns); - mean->d += l.d; - mean->e += l.e; - mean->o += l.o; - mean->s += l.s; - mean->p += l.p; - mean->t += l.t; - MAXUP(peak->d, l.d); - MAXUP(peak->e, l.e); - MAXUP(peak->o, l.o); - MAXUP(peak->s, l.s); - MAXUP(peak->p, l.p); - MAXUP(peak->t, l.t); - MAXUP(rel->e, l.e-l.o); - MAXUP(rel->o, l.o-l.e); - MAXUP(rel->s, l.s-l.t); - MAXUP(rel->p, l.p-l.t); - MAXUP(rel->t, l.t-l.p); - MAXUP(rel->d, l.t-l.s); /* hack */ - } - } - x = (w/8-2)*(h/8); - mean->d /= x; - mean->e /= x; - mean->o /= x; - mean->s /= x; - mean->p /= x; - mean->t /= x; -} - -static void diff_fields(struct frameinfo *fi, mp_image_t *old, mp_image_t *new) -{ - diff_planes(fi, old->planes[0], new->planes[0], - new->w, new->h, old->stride[0], new->stride[0]); -} - -static void stats(struct frameinfo *f) -{ - mp_msg(MSGT_VFILTER, MSGL_V, " pd=%d re=%d ro=%d rp=%d rt=%d rs=%d rd=%d pp=%d pt=%d ps=%d\r", - f->p.d, f->r.e, f->r.o, f->r.p, f->r.t, f->r.s, f->r.d, f->p.p, f->p.t, f->p.s); -} - -static int foo(struct vf_priv_s *p, mp_image_t *new, mp_image_t *cur) -{ - struct frameinfo *f = p->fi; - - f[0] = f[1]; - diff_fields(&f[1], cur, new); - stats(&f[1]); - - // Immediately drop this frame if it's already been used. - if (p->dropnext) { - p->dropnext = 0; - return F_DROP; - } - - // Sometimes a pulldown frame comes all by itself, so both - // its top and bottom field are duplicates from the adjacent - // two frames. We can just drop such a frame, but we - // immediately show the next frame instead to keep the frame - // drops evenly spaced during normal 3:2 pulldown sequences. - if ((3*f[1].r.o < f[1].r.e) && (f[1].r.s < f[1].r.d)) { - p->dropnext = 1; - return F_NEXT; - } - - // If none of these conditions hold, we will consider the frame - // progressive and just show it as-is. - if (!( (3*f[0].r.e < f[0].r.o) || - ((2*f[0].r.d < f[0].r.s) && (f[0].r.s > 1200)) || - ((2*f[1].r.t < f[1].r.p) && (f[1].r.p > 1200)) )) - return F_SHOW; - - // Otherwise, we have to decide whether to merge or drop. - // If the noise metric only increases minimally, we're off - // to a good start... - if (((2*f[1].r.t < 3*f[1].r.p) && (f[1].r.t < 3600)) || - (f[1].r.t < 900) || (f[1].r.d < 900)) { - // ...and if noise decreases or the duplicate even field - // is detected, we go ahead with the merge. - if ((3*f[0].r.e < f[0].r.o) || (2*f[1].r.t < f[1].r.p)) { - p->dropnext = 1; - return F_MERGE; - } - } - return F_DROP; -} - - - -static void copy_image(mp_image_t *dmpi, mp_image_t *mpi, int field) -{ - switch (field) { - case 0: - my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - break; - case 1: - my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0], - mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1], - mpi->planes[1]+mpi->stride[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2], - mpi->planes[2]+mpi->stride[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - break; - case 2: - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, - dmpi->stride[0], mpi->stride[0]); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[2], mpi->stride[2]); - } - break; - } -} - -static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi, double pts) -{ - struct vf_priv_s *p = vf->priv; - int dropflag=0; - - if (!p->dropnext) switch (p->drop) { - case 0: - dropflag = 0; - break; - case 1: - dropflag = (++p->lastdrop >= 5); - break; - case 2: - dropflag = (++p->lastdrop >= 5) && (4*p->inframes <= 5*p->outframes); - break; - } - - if (dropflag) { - //mp_msg(MSGT_VFILTER, MSGL_V, "drop! [%d/%d=%g]\n", - // p->outframes, p->inframes, (float)p->outframes/p->inframes); - mp_msg(MSGT_VFILTER, MSGL_V, "!"); - p->lastdrop = 0; - vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1); - return 0; - } - - p->outframes++; - return vf_next_put_image(vf, dmpi, vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 0)); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - int ret=0; - struct vf_priv_s *p = vf->priv; - - p->inframes++; - - if (p->first) { /* hack */ - p->first = 0; - vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1); - return 1; - } - - if (!p->dmpi) p->dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE, - mpi->width, mpi->height); - /* FIXME -- not correct, off by one frame! */ - p->dmpi->qscale = mpi->qscale; - p->dmpi->qstride = mpi->qstride; - p->dmpi->qscale_type = mpi->qscale_type; - - switch (foo(p, mpi, p->dmpi)) { - case F_DROP: - copy_image(p->dmpi, mpi, 2); - ret = 0; - p->lastdrop = 0; - mp_msg(MSGT_VFILTER, MSGL_V, "DROP\n"); - vf_detc_adjust_pts(&p->ptsbuf, pts, 0, 1); - break; - case F_MERGE: - copy_image(p->dmpi, mpi, 0); - ret = do_put_image(vf, p->dmpi, pts); - copy_image(p->dmpi, mpi, 1); - mp_msg(MSGT_VFILTER, MSGL_V, "MERGE\n"); - p->dmpi = NULL; - break; - case F_NEXT: - copy_image(p->dmpi, mpi, 2); - ret = do_put_image(vf, p->dmpi, pts); - mp_msg(MSGT_VFILTER, MSGL_V, "NEXT\n"); - p->dmpi = NULL; - break; - case F_SHOW: - ret = do_put_image(vf, p->dmpi, pts); - copy_image(p->dmpi, mpi, 2); - mp_msg(MSGT_VFILTER, MSGL_V, "OK\n"); - p->dmpi = NULL; - break; - } - return ret; -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - switch (fmt) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - struct vf_priv_s *p; - vf->put_image = put_image; - vf->query_format = query_format; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); - p->drop = 0; - p->first = 1; - if (args) sscanf(args, "%d", &p->drop); - block_diffs = block_diffs_C; -#if HAVE_MMX && HAVE_EBX_AVAILABLE - if(gCpuCaps.hasMMX) block_diffs = block_diffs_MMX; -#endif - vf_detc_init_pts_buf(&p->ptsbuf); - return 1; -} - -const vf_info_t vf_info_ivtc = { - "inverse telecine, take 2", - "ivtc", - "Rich Felker", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_kerndeint.c b/libmpcodecs/vf_kerndeint.c deleted file mode 100644 index c6fb389f3a..0000000000 --- a/libmpcodecs/vf_kerndeint.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Original AVISynth Filter Copyright (C) 2003 Donald A. Graft - * Adapted to MPlayer by Tobias Diedrich - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include - -#include "mp_msg.h" -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libvo/fastmemcpy.h" - -//===========================================================================// - -struct vf_priv_s { - int frame; - int map; - int order; - int thresh; - int sharp; - int twoway; - int do_deinterlace; -}; - - -/***************************************************************************/ - - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static inline int IsRGB(mp_image_t *mpi) -{ - return mpi->imgfmt == IMGFMT_RGB; -} - -static inline int IsYUY2(mp_image_t *mpi) -{ - return mpi->imgfmt == IMGFMT_YUY2; -} - -#define PLANAR_Y 0 -#define PLANAR_U 1 -#define PLANAR_V 2 - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - int cw= mpi->w >> mpi->chroma_x_shift; - int ch= mpi->h >> mpi->chroma_y_shift; - int W = mpi->w, H = mpi->h; - const unsigned char *prvp, *prvpp, *prvpn, *prvpnn, *prvppp, *prvp4p, *prvp4n; - const unsigned char *srcp_saved; - const unsigned char *srcp, *srcpp, *srcpn, *srcpnn, *srcppp, *srcp3p, *srcp3n, *srcp4p, *srcp4n; - unsigned char *dstp, *dstp_saved; - int src_pitch; - int psrc_pitch; - int dst_pitch; - int x, y, z; - int n = vf->priv->frame++; - int val, hi, lo, w, h; - double valf; - int plane; - int threshold = vf->priv->thresh; - int order = vf->priv->order; - int map = vf->priv->map; - int sharp = vf->priv->sharp; - int twoway = vf->priv->twoway; - mp_image_t *dmpi, *pmpi; - - if(!vf->priv->do_deinterlace) - return vf_next_put_image(vf, mpi, pts); - - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_IP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w,mpi->h); - pmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w,mpi->h); - if(!dmpi) return 0; - - for (z=0; znum_planes; z++) { - if (z == 0) plane = PLANAR_Y; - else if (z == 1) plane = PLANAR_U; - else plane = PLANAR_V; - - h = plane == PLANAR_Y ? H : ch; - w = plane == PLANAR_Y ? W : cw; - - srcp = srcp_saved = mpi->planes[z]; - src_pitch = mpi->stride[z]; - psrc_pitch = pmpi->stride[z]; - dstp = dstp_saved = dmpi->planes[z]; - dst_pitch = dmpi->stride[z]; - srcp = srcp_saved + (1-order) * src_pitch; - dstp = dstp_saved + (1-order) * dst_pitch; - - for (y=0; yplanes[z] + 5*psrc_pitch - (1-order)*psrc_pitch; - prvpp = prvp - psrc_pitch; - prvppp = prvp - 2*psrc_pitch; - prvp4p = prvp - 4*psrc_pitch; - prvpn = prvp + psrc_pitch; - prvpnn = prvp + 2*psrc_pitch; - prvp4n = prvp + 4*psrc_pitch; - srcp = srcp_saved + 5*src_pitch - (1-order)*src_pitch; - srcpp = srcp - src_pitch; - srcppp = srcp - 2*src_pitch; - srcp3p = srcp - 3*src_pitch; - srcp4p = srcp - 4*src_pitch; - srcpn = srcp + src_pitch; - srcpnn = srcp + 2*src_pitch; - srcp3n = srcp + 3*src_pitch; - srcp4n = srcp + 4*src_pitch; - dstp = dstp_saved + 5*dst_pitch - (1-order)*dst_pitch; - for (y = 5 - (1-order); y <= h - 5 - (1-order); y+=2) - { - for (x = 0; x < w; x++) - { - if ((threshold == 0) || (n == 0) || - (abs((int)prvp[x] - (int)srcp[x]) > threshold) || - (abs((int)prvpp[x] - (int)srcpp[x]) > threshold) || - (abs((int)prvpn[x] - (int)srcpn[x]) > threshold)) - { - if (map == 1) - { - int g = x & ~3; - if (IsRGB(mpi) == 1) - { - dstp[g++] = 255; - dstp[g++] = 255; - dstp[g++] = 255; - dstp[g] = 255; - x = g; - } - else if (IsYUY2(mpi) == 1) - { - dstp[g++] = 235; - dstp[g++] = 128; - dstp[g++] = 235; - dstp[g] = 128; - x = g; - } - else - { - if (plane == PLANAR_Y) dstp[x] = 235; - else dstp[x] = 128; - } - } - else - { - if (IsRGB(mpi)) - { - hi = 255; - lo = 0; - } - else if (IsYUY2(mpi)) - { - hi = (x & 1) ? 240 : 235; - lo = 16; - } - else - { - hi = (plane == PLANAR_Y) ? 235 : 240; - lo = 16; - } - - if (sharp == 1) - { - if (twoway == 1) - valf = + 0.526*((int)srcpp[x] + (int)srcpn[x]) - + 0.170*((int)srcp[x] + (int)prvp[x]) - - 0.116*((int)srcppp[x] + (int)srcpnn[x] + (int)prvppp[x] + (int)prvpnn[x]) - - 0.026*((int)srcp3p[x] + (int)srcp3n[x]) - + 0.031*((int)srcp4p[x] + (int)srcp4n[x] + (int)prvp4p[x] + (int)prvp4n[x]); - else - valf = + 0.526*((int)srcpp[x] + (int)srcpn[x]) - + 0.170*((int)prvp[x]) - - 0.116*((int)prvppp[x] + (int)prvpnn[x]) - - 0.026*((int)srcp3p[x] + (int)srcp3n[x]) - + 0.031*((int)prvp4p[x] + (int)prvp4p[x]); - if (valf > hi) valf = hi; - else if (valf < lo) valf = lo; - dstp[x] = (int) valf; - } - else - { - if (twoway == 1) - val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)srcp[x] + (int)prvp[x]) - - (int)(srcppp[x]) - (int)(srcpnn[x]) - - (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4; - else - val = (8*((int)srcpp[x] + (int)srcpn[x]) + 2*((int)prvp[x]) - - (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4; - if (val > hi) val = hi; - else if (val < lo) val = lo; - dstp[x] = (int) val; - } - } - } - else - { - dstp[x] = srcp[x]; - } - } - prvp += 2*psrc_pitch; - prvpp += 2*psrc_pitch; - prvppp += 2*psrc_pitch; - prvpn += 2*psrc_pitch; - prvpnn += 2*psrc_pitch; - prvp4p += 2*psrc_pitch; - prvp4n += 2*psrc_pitch; - srcp += 2*src_pitch; - srcpp += 2*src_pitch; - srcppp += 2*src_pitch; - srcp3p += 2*src_pitch; - srcp4p += 2*src_pitch; - srcpn += 2*src_pitch; - srcpnn += 2*src_pitch; - srcp3n += 2*src_pitch; - srcp4n += 2*src_pitch; - dstp += 2*dst_pitch; - } - - srcp = mpi->planes[z]; - dstp = pmpi->planes[z]; - for (y=0; ypriv->do_deinterlace; - return CONTROL_OK; - case VFCTRL_SET_DEINTERLACE: - vf->priv->do_deinterlace = *(int*)data; - return CONTROL_OK; - } - return vf_next_control (vf, request, data); -} - -static int vf_open(vf_instance_t *vf, char *args){ - - vf->control=control; - vf->config=config; - vf->put_image=put_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - vf->priv->frame = 0; - - vf->priv->map = 0; - vf->priv->order = 0; - vf->priv->thresh = 10; - vf->priv->sharp = 0; - vf->priv->twoway = 0; - vf->priv->do_deinterlace=1; - - if (args) - { - sscanf(args, "%d:%d:%d:%d:%d", - &vf->priv->thresh, &vf->priv->map, - &vf->priv->order, &vf->priv->sharp, - &vf->priv->twoway); - } - if (vf->priv->order > 1) vf->priv->order = 1; - - return 1; -} - -const vf_info_t vf_info_kerndeint = { - "Kernel Deinterlacer", - "kerndeint", - "Donald Graft", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_lavc.c b/libmpcodecs/vf_lavc.c deleted file mode 100644 index 65e93a16cc..0000000000 --- a/libmpcodecs/vf_lavc.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libavcodec/avcodec.h" - -struct vf_priv_s { - unsigned char* outbuf; - int outbuf_size; - AVCodecContext* context; - AVFrame* pic; - AVCodec* codec; - vo_mpegpes_t pes; -}; - -#define lavc_venc_context (*vf->priv->context) - -//===========================================================================// - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - if(vf_next_query_format(vf,IMGFMT_MPEGPES)<=0) return 0; - - lavc_venc_context.width = width; - lavc_venc_context.height = height; - - if(!lavc_venc_context.time_base.num || !lavc_venc_context.time_base.den){ - // guess FPS: - switch(height){ - case 240: - case 480: - lavc_venc_context.time_base= (AVRational){1001,30000}; - break; - case 576: - case 288: - default: - lavc_venc_context.time_base= (AVRational){1,25}; - break; -// lavc_venc_context.frame_rate=vo_fps*FRAME_RATE_BASE; // same as src - } - } - - free(vf->priv->outbuf); - - vf->priv->outbuf_size=10000+width*height; // must be enough! - vf->priv->outbuf = malloc(vf->priv->outbuf_size); - - if (avcodec_open2(&lavc_venc_context, vf->priv->codec, NULL) != 0) { - mp_tmsg(MSGT_VFILTER,MSGL_ERR,"Could not open codec.\n"); - return 0; - } - - return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_MPEGPES); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t* dmpi; - int out_size; - AVFrame *pic= vf->priv->pic; - - pic->data[0]=mpi->planes[0]; - pic->data[1]=mpi->planes[1]; - pic->data[2]=mpi->planes[2]; - pic->linesize[0]=mpi->stride[0]; - pic->linesize[1]=mpi->stride[1]; - pic->linesize[2]=mpi->stride[2]; - - out_size = avcodec_encode_video(&lavc_venc_context, - vf->priv->outbuf, vf->priv->outbuf_size, pic); - - if(out_size<=0) return 1; - - dmpi=vf_get_image(vf->next,IMGFMT_MPEGPES, - MP_IMGTYPE_EXPORT, 0, - mpi->w, mpi->h); - - vf->priv->pes.data=vf->priv->outbuf; - vf->priv->pes.size=out_size; - vf->priv->pes.id=0x1E0; - vf->priv->pes.timestamp=-1; // dunno - - dmpi->planes[0]=(unsigned char*)&vf->priv->pes; - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - return vf_next_query_format(vf, IMGFMT_MPEGPES) & (~(VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_ACCEPT_STRIDE)); - } - return 0; -} - -static int vf_open(vf_instance_t *vf, char *args){ - int p_quality=0; - float p_fps=0; - - vf->config=config; - vf->put_image=put_image; - vf->query_format=query_format; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv,0,sizeof(struct vf_priv_s)); - - vf->priv->codec = (AVCodec *)avcodec_find_encoder_by_name("mpeg1video"); - if (!vf->priv->codec) { - mp_tmsg(MSGT_VFILTER,MSGL_ERR,"Cannot find codec '%s' in libavcodec...\n", "mpeg1video"); - return 0; - } - - vf->priv->context=avcodec_alloc_context3(vf->priv->codec); - vf->priv->pic = avcodec_alloc_frame(); - - // TODO: parse args -> - if(args) sscanf(args, "%d:%f", &p_quality, &p_fps); - - if(p_quality<32){ - // fixed qscale - lavc_venc_context.flags = CODEC_FLAG_QSCALE; - lavc_venc_context.global_quality = - vf->priv->pic->quality = (int)(FF_QP2LAMBDA * ((p_quality<1) ? 1 : p_quality) + 0.5); - } else { - // fixed bitrate (in kbits) - lavc_venc_context.bit_rate = 1000*p_quality; - } - lavc_venc_context.time_base.num = 1000*1001; - lavc_venc_context.time_base.den = (p_fps<1.0) ? 1000*1001*25 : (p_fps * lavc_venc_context.time_base.num); - lavc_venc_context.gop_size = 0; // I-only - lavc_venc_context.pix_fmt= PIX_FMT_YUV420P; - - return 1; -} - -const vf_info_t vf_info_lavc = { - "realtime mpeg1 encoding with libavcodec", - "lavc", - "A'rpi", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_lavcdeint.c b/libmpcodecs/vf_lavcdeint.c deleted file mode 100644 index 3a67c8db59..0000000000 --- a/libmpcodecs/vf_lavcdeint.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libavcodec/avcodec.h" - - -struct vf_priv_s -{ - int width, height; - int pix_fmt; -}; - -/* Support for avcodec's built-in deinterlacer. - * Based on vf_lavc.c - */ - -//===========================================================================// - - -/* Convert mplayer's IMGFMT_* to avcodec's PIX_FMT_* for the supported - * IMGFMT's, and return -1 if the deinterlacer doesn't support - * that format (-1 because 0 is a valid PIX_FMT). - */ -/* The deinterlacer supports planer 4:2:0, 4:2:2, and 4:4:4 YUV */ -static int -imgfmt_to_pixfmt (int imgfmt) -{ - switch(imgfmt) - { - /* I hope I got all the supported formats */ - - /* 4:2:0 */ - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - return PIX_FMT_YUV420P; - break; - -#if 0 - /* 4:2:2 */ - case IMGFMT_UYVY: - case IMGFMT_UYNV: - case IMGFMT_Y422: - case IMGFMT_YUY2: - case IMGFMT_YUNV: - case IMGFMT_YVYU: - case IMGFMT_Y42T: - case IMGFMT_V422: - case IMGFMT_V655: - return PIX_FMT_YUV422P; - break; -#endif - - /* Are there any _planar_ YUV 4:4:4 formats? */ - - default: - return -1; - } -} - - -static int -config (struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - struct vf_priv_s *priv = vf->priv; - - priv->pix_fmt = imgfmt_to_pixfmt(outfmt); - if(priv->pix_fmt == -1) - return 0; - - /* The deinterlacer will fail if this is false */ - if ((width & 3) != 0 || (height & 3) != 0) - return 0; - - /* If we get here, the deinterlacer is guaranteed not to fail */ - - priv->width = width; - priv->height = height; - - return vf_next_config(vf, - width, height, - d_width, d_height, - flags, outfmt); -} - -static int -put_image (struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - struct vf_priv_s *priv = vf->priv; - mp_image_t* dmpi; - AVPicture pic; - AVPicture lavc_picture; - - lavc_picture.data[0] = mpi->planes[0]; - lavc_picture.data[1] = mpi->planes[1]; - lavc_picture.data[2] = mpi->planes[2]; - lavc_picture.linesize[0] = mpi->stride[0]; - lavc_picture.linesize[1] = mpi->stride[1]; - lavc_picture.linesize[2] = mpi->stride[2]; - - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - priv->width, priv->height); - - pic.data[0] = dmpi->planes[0]; - pic.data[1] = dmpi->planes[1]; - pic.data[2] = dmpi->planes[2]; - pic.linesize[0] = dmpi->stride[0]; - pic.linesize[1] = dmpi->stride[1]; - pic.linesize[2] = dmpi->stride[2]; - - if (avpicture_deinterlace(&pic, &lavc_picture, - priv->pix_fmt, priv->width, priv->height) < 0) - { - /* This should not happen -- see config() */ - return 0; - } - - return vf_next_put_image(vf, dmpi, pts); -} - - -static int -query_format (struct vf_instance *vf, unsigned int fmt) -{ - if(imgfmt_to_pixfmt(fmt) == -1) - return 0; - - return vf_next_query_format(vf,fmt); -} - - -static int -vf_open(vf_instance_t *vf, char *args) -{ - /* We don't have any args */ - (void) args; - - vf->config = config; - vf->put_image = put_image; - vf->query_format = query_format; - vf->priv = malloc(sizeof(struct vf_priv_s)); - memset(vf->priv,0,sizeof(struct vf_priv_s)); - - return 1; -} - - -const vf_info_t vf_info_lavcdeint = { - "libavcodec's deinterlacing filter", - "lavcdeint", - "Joe Rabinoff", - "libavcodec's internal deinterlacer, in case you don't like " - "the builtin ones (invoked with -pp or -npp)", - vf_open, - NULL -}; - - -//===========================================================================// diff --git a/libmpcodecs/vf_mcdeint.c b/libmpcodecs/vf_mcdeint.c deleted file mode 100644 index 82635e5dfd..0000000000 --- a/libmpcodecs/vf_mcdeint.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) 2006 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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. - */ - - -/* -Known Issues: -* The motion estimation is somewhat at the mercy of the input, if the input - frames are created purely based on spatial interpolation then for example - a thin black line or another random and not interpolateable pattern - will cause problems - Note: completly ignoring the "unavailable" lines during motion estimation - didnt look any better, so the most obvious solution would be to improve - tfields or penalize problematic motion vectors ... - -* If non iterative ME is used then snow currently ignores the OBMC window - and as a result sometimes creates artifacts - -* only past frames are used, we should ideally use future frames too, something - like filtering the whole movie in forward and then backward direction seems - like a interresting idea but the current filter framework is FAR from - supporting such things - -* combining the motion compensated image with the input image also isnt - as trivial as it seems, simple blindly taking even lines from one and - odd ones from the other doesnt work at all as ME/MC sometimes simple - has nothing in the previous frames which matches the current, the current - algo has been found by trial and error and almost certainly can be - improved ... -*/ - -#include -#include -#include -#include -#include - -#include "mp_msg.h" -#include "cpudetect.h" - -#include "libavutil/intreadwrite.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#define MIN(a,b) ((a) > (b) ? (b) : (a)) -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#define ABS(a) ((a) > 0 ? (a) : (-(a))) - -//===========================================================================// - -struct vf_priv_s { - int mode; - int qp; - int parity; -#if 0 - int temp_stride[3]; - uint8_t *src[3]; - int16_t *temp[3]; -#endif - int outbuf_size; - uint8_t *outbuf; - AVCodecContext *avctx_enc; - AVFrame *frame; - AVFrame *frame_dec; -}; - -static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int dst_stride[3], int src_stride[3], int width, int height){ - int x, y, i; - int out_size; - - for(i=0; i<3; i++){ - p->frame->data[i]= src[i]; - p->frame->linesize[i]= src_stride[i]; - } - - p->avctx_enc->me_cmp= - p->avctx_enc->me_sub_cmp= FF_CMP_SAD /*| (p->parity ? FF_CMP_ODD : FF_CMP_EVEN)*/; - p->frame->quality= p->qp*FF_QP2LAMBDA; - out_size = avcodec_encode_video(p->avctx_enc, p->outbuf, p->outbuf_size, p->frame); - p->frame_dec = p->avctx_enc->coded_frame; - - for(i=0; i<3; i++){ - int is_chroma= !!i; - int w= width >>is_chroma; - int h= height>>is_chroma; - int fils= p->frame_dec->linesize[i]; - int srcs= src_stride[i]; - - for(y=0; yparity) & 1){ - for(x=0; x=0 && (x+2)+(y+1)*wframe_dec->data[i][x + y*fils]; - uint8_t *srcp= &src[i][x + y*srcs]; - int diff0= filp[-fils] - srcp[-srcs]; - int diff1= filp[+fils] - srcp[+srcs]; - int spatial_score= ABS(srcp[-srcs-1] - srcp[+srcs-1]) - +ABS(srcp[-srcs ] - srcp[+srcs ]) - +ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1; - int temp= filp[0]; - -#define CHECK(j)\ - { int score= ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\ - + ABS(srcp[-srcs +j] - srcp[+srcs -j])\ - + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\ - if(score < spatial_score){\ - spatial_score= score;\ - diff0= filp[-fils+j] - srcp[-srcs+j];\ - diff1= filp[+fils-j] - srcp[+srcs-j]; - - CHECK(-1) CHECK(-2) }} }} - CHECK( 1) CHECK( 2) }} }} -#if 0 - if((diff0 ^ diff1) > 0){ - int mindiff= ABS(diff0) > ABS(diff1) ? diff1 : diff0; - temp-= mindiff; - } -#elif 1 - if(diff0 + diff1 > 0) - temp-= (diff0 + diff1 - ABS( ABS(diff0) - ABS(diff1) )/2)/2; - else - temp-= (diff0 + diff1 + ABS( ABS(diff0) - ABS(diff1) )/2)/2; -#else - temp-= (diff0 + diff1)/2; -#endif -#if 1 - filp[0]= - dst[i][x + y*dst_stride[i]]= temp > 255U ? ~(temp>>31) : temp; -#else - dst[i][x + y*dst_stride[i]]= filp[0]; - filp[0]= temp > 255U ? ~(temp>>31) : temp; -#endif - }else - dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils]; - } - } - } - for(y=0; yparity) & 1)){ - for(x=0; xframe_dec->data[i][x + y*fils]= - dst[i][x + y*dst_stride[i]]= src[i][x + y*srcs]; -#else - dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils]; - p->frame_dec->data[i][x + y*fils]= src[i][x + y*srcs]; -#endif - } - } - } - } - p->parity ^= 1; - -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - int i; - AVCodec *enc= avcodec_find_encoder(CODEC_ID_SNOW); - - for(i=0; i<3; i++){ - AVCodecContext *avctx_enc; -#if 0 - int is_chroma= !!i; - int w= ((width + 31) & (~31))>>is_chroma; - int h= ((height + 31) & (~31))>>is_chroma; - - vf->priv->temp_stride[i]= w; - vf->priv->temp[i]= malloc(vf->priv->temp_stride[i]*h*sizeof(int16_t)); - vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t)); -#endif - avctx_enc= - vf->priv->avctx_enc= avcodec_alloc_context(); - avctx_enc->width = width; - avctx_enc->height = height; - avctx_enc->time_base= (AVRational){1,25}; // meaningless - avctx_enc->gop_size = 300; - avctx_enc->max_b_frames= 0; - avctx_enc->pix_fmt = PIX_FMT_YUV420P; - avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY; - avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; - avctx_enc->global_quality= 1; - avctx_enc->flags2= CODEC_FLAG2_MEMC_ONLY; - avctx_enc->me_cmp= - avctx_enc->me_sub_cmp= FF_CMP_SAD; //SSE; - avctx_enc->mb_cmp= FF_CMP_SSE; - - switch(vf->priv->mode){ - case 3: - avctx_enc->refs= 3; - case 2: - avctx_enc->me_method= ME_ITER; - case 1: - avctx_enc->flags |= CODEC_FLAG_4MV; - avctx_enc->dia_size=2; -// avctx_enc->mb_decision = MB_DECISION_RD; - case 0: - avctx_enc->flags |= CODEC_FLAG_QPEL; - } - - avcodec_open(avctx_enc, enc); - - } - vf->priv->frame= avcodec_alloc_frame(); - - vf->priv->outbuf_size= width*height*10; - vf->priv->outbuf= malloc(vf->priv->outbuf_size); - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi){ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change -return; //caused problems, dunno why - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // no DR, so get a new image! hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->width,mpi->height); - vf_clone_mpi_attributes(dmpi, mpi); - }else{ - dmpi=vf->dmpi; - } - - filter(vf->priv, dmpi->planes, mpi->planes, dmpi->stride, mpi->stride, mpi->w, mpi->h); - - return vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf){ - if(!vf->priv) return; - -#if 0 - for(i=0; i<3; i++){ - free(vf->priv->temp[i]); - vf->priv->temp[i]= NULL; - free(vf->priv->src[i]); - vf->priv->src[i]= NULL; - } -#endif - if (vf->priv->avctx_enc) { - avcodec_close(vf->priv->avctx_enc); - av_freep(&vf->priv->avctx_enc); - } - - free(vf->priv->outbuf); - free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_Y800: - case IMGFMT_Y8: - return vf_next_query_format(vf,fmt); - } - return 0; -} - -static int vf_open(vf_instance_t *vf, char *args){ - - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - vf->priv->mode=0; - vf->priv->parity= -1; - vf->priv->qp=1; - - if (args) sscanf(args, "%d:%d:%d", &vf->priv->mode, &vf->priv->parity, &vf->priv->qp); - - return 1; -} - -const vf_info_t vf_info_mcdeint = { - "motion compensating deinterlacer", - "mcdeint", - "Michael Niedermayer", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_ow.c b/libmpcodecs/vf_ow.c deleted file mode 100644 index f7fb02db72..0000000000 --- a/libmpcodecs/vf_ow.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2007 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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. - */ - -/** - * @todo try to change to int - * @todo try lifting based implementation - * @todo optimize optimize optimize - * @todo hard tresholding - * @todo use QP to decide filter strength - * @todo wavelet normalization / least squares optimal signal vs. noise thresholds - */ - -#include -#include -#include -#include - -#include "mp_msg.h" -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -//===========================================================================// -static const uint8_t __attribute__((aligned(8))) dither[8][8]={ -{ 0, 48, 12, 60, 3, 51, 15, 63, }, -{ 32, 16, 44, 28, 35, 19, 47, 31, }, -{ 8, 56, 4, 52, 11, 59, 7, 55, }, -{ 40, 24, 36, 20, 43, 27, 39, 23, }, -{ 2, 50, 14, 62, 1, 49, 13, 61, }, -{ 34, 18, 46, 30, 33, 17, 45, 29, }, -{ 10, 58, 6, 54, 9, 57, 5, 53, }, -{ 42, 26, 38, 22, 41, 25, 37, 21, }, -}; -//FIXME the above is duplicated in many filters - -struct vf_priv_s { - float strength[2]; - float delta; - int mode; - int depth; - float *plane[16][4]; - int stride; -}; - -#define S 1.41421356237 //sqrt(2) - -static const double coeff[2][5]={ - { - 0.6029490182363579 *S, - 0.2668641184428723 *S, - -0.07822326652898785 *S, - -0.01686411844287495 *S, - 0.02674875741080976 *S - },{ - 1.115087052456994 /S, - -0.5912717631142470 /S, - -0.05754352622849957 /S, - 0.09127176311424948 /S - } -}; - -static const double icoeff[2][5]={ - { - 1.115087052456994 /S, - 0.5912717631142470 /S, - -0.05754352622849957 /S, - -0.09127176311424948 /S - },{ - 0.6029490182363579 *S, - -0.2668641184428723 *S, - -0.07822326652898785 *S, - 0.01686411844287495 *S, - 0.02674875741080976 *S - } -}; -#undef S - -static inline int mirror(int x, int w){ - while((unsigned)x > (unsigned)w){ - x=-x; - if(x<0) x+= 2*w; - } - return x; -} - -static inline void decompose(float *dstL, float *dstH, float *src, int stride, int w){ - int x, i; - for(x=0; xstrength[!is_luma]; - int depth= p->depth; - - while(1< width || 1< height) - depth--; - - for(y=0; yplane[0][0][x + y*p->stride]= src[x + y*src_stride]; - - for(i=0; iplane[i+1], p->plane[i][0], p->plane[0]+1,p->stride, 1<plane[i+1][j][x + y*p->stride]; - if (v> s) v-=s; - else if(v<-s) v+=s; - else v =0; - p->plane[i+1][j][x + y*p->stride]= v; - } - } - } - } - for(i=depth-1; i>=0; i--){ - compose2D2(p->plane[i][0], p->plane[i+1], p->plane[0]+1, p->stride, 1<plane[0][0][x + y*p->stride] + dither[x&7][y&7]*(1.0/64) + 1.0/128; //yes the rounding is insane but optimal :) -// double e= i - src[x + y*src_stride]; -// sum += e*e; - if((unsigned)i > 255U) i= ~(i>>31); - dst[x + y*dst_stride]= i; - } - -// printf("%f\n", sum/height/width); -} - -static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){ - int h= (height+15)&(~15); - int i,j; - - vf->priv->stride= (width+15)&(~15); - for(j=0; j<4; j++){ - for(i=0; i<=vf->priv->depth; i++) - vf->priv->plane[i][j]= malloc(vf->priv->stride*h*sizeof(vf->priv->plane[0][0][0])); - } - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi){ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // no DR, so get a new image! hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->width,mpi->height); - vf_clone_mpi_attributes(dmpi, mpi); - }else{ - dmpi=vf->dmpi; - } - - filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, 1); - filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0); - filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0); - - return vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf){ - int i,j; - if(!vf->priv) return; - - for(j=0; j<4; j++){ - for(i=0; i<16; i++){ - free(vf->priv->plane[i][j]); - vf->priv->plane[i][j]= NULL; - } - } - - free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf,fmt); - } - return 0; -} - - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - vf->priv->depth= 8; - vf->priv->strength[0]= 1.0; - vf->priv->strength[1]= 1.0; - vf->priv->delta= 1.0; - - if (args) sscanf(args, "%d:%f:%f:%d:%f", &vf->priv->depth, - &vf->priv->strength[0], - &vf->priv->strength[1], - &vf->priv->mode, - &vf->priv->delta); - - return 1; -} - -const vf_info_t vf_info_ow = { - "overcomplete wavelet denoiser", - "ow", - "Michael Niedermayer", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_palette.c b/libmpcodecs/vf_palette.c deleted file mode 100644 index 17670f3eb0..0000000000 --- a/libmpcodecs/vf_palette.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "mpbswap.h" - -#include "libswscale/swscale.h" - -//===========================================================================// - -// commented out 16 and 15 bit output support, because the conversion -// routines are incorrrect. they assume the palette to be of the same -// depth as the output, which is incorrect. --Joey - -static const unsigned int bgr_list[]={ - IMGFMT_BGR32, - IMGFMT_BGR24, -// IMGFMT_BGR16, -// IMGFMT_BGR15, - 0 -}; -static const unsigned int rgb_list[]={ - IMGFMT_RGB32, - IMGFMT_RGB24, -// IMGFMT_RGB16, -// IMGFMT_RGB15, - 0 -}; - -/** - * Palette is assumed to contain BGR16, see rgb32to16 to convert the palette. - */ -static void palette8torgb16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette) -{ - long i; - for (i=0; inext->query_format(vf->next,*p); - mp_msg(MSGT_VFILTER,MSGL_DBG2,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3); - if(ret&VFCAP_CSP_SUPPORTED_BY_HW){ best=*p; break;} // no conversion -> bingo! - if(ret&VFCAP_CSP_SUPPORTED && !best) best=*p; // best with conversion - ++p; - } - return best; -} - -//===========================================================================// - -struct vf_priv_s { - unsigned int fmt; - int pal_msg; -}; - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - if (!vf->priv->fmt) - vf->priv->fmt=find_best(vf,outfmt); - if(!vf->priv->fmt){ - // no matching fmt, so force one... - if(outfmt==IMGFMT_RGB8) vf->priv->fmt=IMGFMT_RGB32; - else if(outfmt==IMGFMT_BGR8) vf->priv->fmt=IMGFMT_BGR32; - else return 0; - } - return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - uint8_t *old_palette = mpi->planes[1]; - - // hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,vf->priv->fmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w, mpi->h); - - if (!mpi->planes[1]) - { - if(!vf->priv->pal_msg){ - mp_msg(MSGT_VFILTER,MSGL_V,"[%s] no palette given, assuming builtin grayscale one\n",vf->info->name); - vf->priv->pal_msg=1; - } - mpi->planes[1] = (unsigned char*)gray_pal; - } - - if(mpi->w==mpi->stride[0] && dmpi->w*(dmpi->bpp>>3)==dmpi->stride[0]){ - // no stride conversion needed - switch(IMGFMT_RGB_DEPTH(dmpi->imgfmt)){ - case 15: - case 16: - if (IMGFMT_IS_BGR(dmpi->imgfmt)) - palette8tobgr16(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); - else - palette8torgb16(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); - break; - case 24: - if (IMGFMT_IS_BGR(dmpi->imgfmt)) - sws_convertPalette8ToPacked24(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); - else - sws_convertPalette8ToPacked24(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); - break; - case 32: - if (IMGFMT_IS_BGR(dmpi->imgfmt)) - sws_convertPalette8ToPacked32(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); - else - sws_convertPalette8ToPacked32(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]); - break; - } - } else { - int y; - for(y=0;yh;y++){ - unsigned char* src=mpi->planes[0]+y*mpi->stride[0]; - unsigned char* dst=dmpi->planes[0]+y*dmpi->stride[0]; - switch(IMGFMT_RGB_DEPTH(dmpi->imgfmt)){ - case 15: - case 16: - if (IMGFMT_IS_BGR(dmpi->imgfmt)) - palette8tobgr16(src,dst,mpi->w,mpi->planes[1]); - else - palette8torgb16(src,dst,mpi->w,mpi->planes[1]); - break; - case 24: - if (IMGFMT_IS_BGR(dmpi->imgfmt)) - sws_convertPalette8ToPacked24(src,dst,mpi->w,mpi->planes[1]); - else - sws_convertPalette8ToPacked24(src,dst,mpi->w,mpi->planes[1]); - break; - case 32: - if (IMGFMT_IS_BGR(dmpi->imgfmt)) - sws_convertPalette8ToPacked32(src,dst,mpi->w,mpi->planes[1]); - else - sws_convertPalette8ToPacked32(src,dst,mpi->w,mpi->planes[1]); - break; - } - } - } - mpi->planes[1] = old_palette; - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - int best=find_best(vf,fmt); - if(!best) return 0; // no match - return vf->next->query_format(vf->next,best); -} - -static void uninit(vf_instance_t *vf) { - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args){ - unsigned int i; - vf->config=config; - vf->uninit=uninit; - vf->put_image=put_image; - vf->query_format=query_format; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - for(i=0;i<256;i++) gray_pal[i]=0x01010101*i; - if (args) - { - if (!strcasecmp(args,"rgb15")) vf->priv->fmt=IMGFMT_RGB15; else - if (!strcasecmp(args,"rgb16")) vf->priv->fmt=IMGFMT_RGB16; else - if (!strcasecmp(args,"rgb24")) vf->priv->fmt=IMGFMT_RGB24; else - if (!strcasecmp(args,"rgb32")) vf->priv->fmt=IMGFMT_RGB32; else - if (!strcasecmp(args,"bgr15")) vf->priv->fmt=IMGFMT_BGR15; else - if (!strcasecmp(args,"bgr16")) vf->priv->fmt=IMGFMT_BGR16; else - if (!strcasecmp(args,"bgr24")) vf->priv->fmt=IMGFMT_BGR24; else - if (!strcasecmp(args,"bgr32")) vf->priv->fmt=IMGFMT_BGR32; else - { - mp_tmsg(MSGT_VFILTER, MSGL_WARN, "[VF_FORMAT] Unknown format name: '%s'.\n", args); - return 0; - } - } - return 1; -} - -const vf_info_t vf_info_palette = { - "8bpp indexed (using palette) -> BGR 15/16/24/32 conversion", - "palette", - "A'rpi & Alex", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_perspective.c b/libmpcodecs/vf_perspective.c deleted file mode 100644 index df196bb1c9..0000000000 --- a/libmpcodecs/vf_perspective.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (C) 2002 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "libavutil/mem.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#define SUB_PIXEL_BITS 8 -#define SUB_PIXELS (1<ref; - int x,y; - - g= ( (ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0])*(ref[2][1] - ref[3][1]) - - (ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1])*(ref[2][0] - ref[3][0]))*H; - h= ( (ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1])*(ref[1][0] - ref[3][0]) - - (ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0])*(ref[1][1] - ref[3][1]))*W; - D= (ref[1][0] - ref[3][0])*(ref[2][1] - ref[3][1]) - - (ref[2][0] - ref[3][0])*(ref[1][1] - ref[3][1]); - - a= D*(ref[1][0] - ref[0][0])*H + g*ref[1][0]; - b= D*(ref[2][0] - ref[0][0])*W + h*ref[2][0]; - c= D*ref[0][0]*W*H; - d= D*(ref[1][1] - ref[0][1])*H + g*ref[1][1]; - e= D*(ref[2][1] - ref[0][1])*W + h*ref[2][1]; - f= D*ref[0][1]*W*H; - - for(y=0; ypv[x + y*W][0]= u; - priv->pv[x + y*W][1]= v; - } - } -} - -static double getCoeff(double d){ - double A= -0.60; - double coeff; - - d= fabs(d); - - // Equation is from VirtualDub - if(d<1.0) - coeff = (1.0 - (A+3.0)*d*d + (A+2.0)*d*d*d); - else if(d<2.0) - coeff = (-4.0*A + 8.0*A*d - 5.0*A*d*d + A*d*d*d); - else - coeff=0.0; - - return coeff; -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - int i, j; - - vf->priv->pvStride= width; - vf->priv->pv= av_malloc(width*height*2*sizeof(int32_t)); - initPv(vf->priv, width, height); - - for(i=0; ipriv->coeff[i][j]= (int)floor((1<priv) return; - - av_free(vf->priv->pv); - vf->priv->pv= NULL; - - free(vf->priv); - vf->priv=NULL; -} - -static inline void resampleCubic(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, struct vf_priv_s *privParam, int xShift, int yShift){ - int x, y; - struct vf_priv_s priv= *privParam; - - for(y=0; y>xShift; - v= priv.pv[sx + sy*priv.pvStride][1]>>yShift; - subU= u & (SUB_PIXELS-1); - subV= v & (SUB_PIXELS-1); - u >>= SUB_PIXEL_BITS; - v >>= SUB_PIXEL_BITS; - - if(u>0 && v>0 && u=h) iy=h-1; - for(dx=0; dx<4; dx++){ - int ix= u + dx - 1; - if (ix< 0) ix=0; - else if(ix>=w) ix=w-1; - - sum+= priv.coeff[subU][dx]*priv.coeff[subV][dy] - *src[ ix + iy*srcStride]; - } - } - } - sum= (sum + (1<<(COEFF_BITS*2-1)) ) >> (COEFF_BITS*2); - if(sum&~255){ - if(sum<0) sum=0; - else sum=255; - } - dst[ x + y*dstStride]= sum; - } - } -} - -static inline void resampleLinear(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, - struct vf_priv_s *privParam, int xShift, int yShift){ - int x, y; - struct vf_priv_s priv= *privParam; - - for(y=0; y>xShift; - v= priv.pv[sx + sy*priv.pvStride][1]>>yShift; - subU= u & (SUB_PIXELS-1); - subV= v & (SUB_PIXELS-1); - u >>= SUB_PIXEL_BITS; - v >>= SUB_PIXEL_BITS; - index= u + v*srcStride; - subUI= SUB_PIXELS - subU; - subVI= SUB_PIXELS - subV; - - if((unsigned)u < (unsigned)(w - 1)){ - if((unsigned)v < (unsigned)(h - 1)){ - sum= subVI*(subUI*src[index ] + subU*src[index +1]) - +subV *(subUI*src[index+srcStride] + subU*src[index+srcStride+1]); - sum= (sum + (1<<(SUB_PIXEL_BITS*2-1)) ) >> (SUB_PIXEL_BITS*2); - }else{ - if(v<0) v= 0; - else v= h-1; - index= u + v*srcStride; - sum= subUI*src[index] + subU*src[index+1]; - sum= (sum + (1<<(SUB_PIXEL_BITS-1)) ) >> SUB_PIXEL_BITS; - } - }else{ - if((unsigned)v < (unsigned)(h - 1)){ - if(u<0) u= 0; - else u= w-1; - index= u + v*srcStride; - sum= subVI*src[index] + subV*src[index+srcStride]; - sum= (sum + (1<<(SUB_PIXEL_BITS-1)) ) >> SUB_PIXEL_BITS; - }else{ - if(u<0) u= 0; - else u= w-1; - if(v<0) v= 0; - else v= h-1; - index= u + v*srcStride; - sum= src[index]; - } - } - if(sum&~255){ - if(sum<0) sum=0; - else sum=255; - } - dst[ x + y*dstStride]= sum; - } - } -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - int cw= mpi->w >> mpi->chroma_x_shift; - int ch= mpi->h >> mpi->chroma_y_shift; - - mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w,mpi->h); - - assert(mpi->flags&MP_IMGFLAG_PLANAR); - - if(vf->priv->cubic){ - resampleCubic(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], - vf->priv, 0, 0); - resampleCubic(dmpi->planes[1], mpi->planes[1], cw , ch , dmpi->stride[1], mpi->stride[1], - vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift); - resampleCubic(dmpi->planes[2], mpi->planes[2], cw , ch , dmpi->stride[2], mpi->stride[2], - vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift); - }else{ - resampleLinear(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], - vf->priv, 0, 0); - resampleLinear(dmpi->planes[1], mpi->planes[1], cw , ch , dmpi->stride[1], mpi->stride[1], - vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift); - resampleLinear(dmpi->planes[2], mpi->planes[2], cw , ch , dmpi->stride[2], mpi->stride[2], - vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift); - } - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt) - { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_YVU9: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int vf_open(vf_instance_t *vf, char *args){ - int e; - - vf->config=config; - vf->put_image=put_image; -// vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - if(args==NULL) return 0; - - e=sscanf(args, "%lf:%lf:%lf:%lf:%lf:%lf:%lf:%lf:%d", - &vf->priv->ref[0][0], &vf->priv->ref[0][1], - &vf->priv->ref[1][0], &vf->priv->ref[1][1], - &vf->priv->ref[2][0], &vf->priv->ref[2][1], - &vf->priv->ref[3][0], &vf->priv->ref[3][1], - &vf->priv->cubic - ); - - if(e!=9) - return 0; - - return 1; -} - -const vf_info_t vf_info_perspective = { - "perspective correcture", - "perspective", - "Michael Niedermayer", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_pp7.c b/libmpcodecs/vf_pp7.c deleted file mode 100644 index 0a30022576..0000000000 --- a/libmpcodecs/vf_pp7.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright (C) 2005 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include - -#include "config.h" - -#include "mp_msg.h" -#include "cpudetect.h" - -#include "libavutil/mem.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libvo/fastmemcpy.h" - -#define XMIN(a,b) ((a) < (b) ? (a) : (b)) -#define XMAX(a,b) ((a) > (b) ? (a) : (b)) - -typedef short DCTELEM; - -//===========================================================================// -static const uint8_t __attribute__((aligned(8))) dither[8][8]={ -{ 0, 48, 12, 60, 3, 51, 15, 63, }, -{ 32, 16, 44, 28, 35, 19, 47, 31, }, -{ 8, 56, 4, 52, 11, 59, 7, 55, }, -{ 40, 24, 36, 20, 43, 27, 39, 23, }, -{ 2, 50, 14, 62, 1, 49, 13, 61, }, -{ 34, 18, 46, 30, 33, 17, 45, 29, }, -{ 10, 58, 6, 54, 9, 57, 5, 53, }, -{ 42, 26, 38, 22, 41, 25, 37, 21, }, -}; - -struct vf_priv_s { - int qp; - int mode; - int mpeg2; - int temp_stride; - uint8_t *src; -}; -#if 0 -static inline void dct7_c(DCTELEM *dst, int s0, int s1, int s2, int s3, int step){ - int s, d; - int dst2[64]; -//#define S0 (1024/0.37796447300922719759) -#define C0 ((int)(1024*0.37796447300922719759+0.5)) //sqrt(1/7) -#define C1 ((int)(1024*0.53452248382484879308/6+0.5)) //sqrt(2/7)/6 - -#define C2 ((int)(1024*0.45221175985034745004/2+0.5)) -#define C3 ((int)(1024*0.36264567479870879474/2+0.5)) - -//0.1962505182412941918 0.0149276808419397944-0.2111781990832339584 -#define C4 ((int)(1024*0.1962505182412941918+0.5)) -#define C5 ((int)(1024*0.0149276808419397944+0.5)) -//#define C6 ((int)(1024*0.2111781990832339584+0.5)) -#if 0 - s= s0 + s1 + s2; - dst[0*step] = ((s + s3)*C0 + 512) >> 10; - s= (s - 6*s3)*C1 + 512; - d= (s0-s2)*C4 + (s1-s2)*C5; - dst[1*step] = (s + 2*d)>>10; - s -= d; - d= (s1-s0)*C2 + (s1-s2)*C3; - dst[2*step] = (s + d)>>10; - dst[3*step] = (s - d)>>10; -#elif 1 - s = s3+s3; - s3= s-s0; - s0= s+s0; - s = s2+s1; - s2= s2-s1; - dst[0*step]= s0 + s; - dst[2*step]= s0 - s; - dst[1*step]= 2*s3 + s2; - dst[3*step]= s3 - 2*s2; -#else - int i,j,n=7; - for(i=0; i<7; i+=2){ - dst2[i*step/2]= 0; - for(j=0; j<4; j++) - dst2[i*step/2] += src[j*step] * cos(i*M_PI/n*(j+0.5)) * sqrt((i?2.0:1.0)/n); - if(fabs(dst2[i*step/2] - dst[i*step/2]) > 20) - printf("%d %d %d (%d %d %d %d) -> (%d %d %d %d)\n", i,dst2[i*step/2], dst[i*step/2],src[0*step], src[1*step], src[2*step], src[3*step], dst[0*step], dst[1*step],dst[2*step],dst[3*step]); - } -#endif -} -#endif - -static inline void dctA_c(DCTELEM *dst, uint8_t *src, int stride){ - int i; - - for(i=0; i<4; i++){ - int s0= src[0*stride] + src[6*stride]; - int s1= src[1*stride] + src[5*stride]; - int s2= src[2*stride] + src[4*stride]; - int s3= src[3*stride]; - int s= s3+s3; - s3= s-s0; - s0= s+s0; - s = s2+s1; - s2= s2-s1; - dst[0]= s0 + s; - dst[2]= s0 - s; - dst[1]= 2*s3 + s2; - dst[3]= s3 - 2*s2; - src++; - dst+=4; - } -} - -static void dctB_c(DCTELEM *dst, DCTELEM *src){ - int i; - - for(i=0; i<4; i++){ - int s0= src[0*4] + src[6*4]; - int s1= src[1*4] + src[5*4]; - int s2= src[2*4] + src[4*4]; - int s3= src[3*4]; - int s= s3+s3; - s3= s-s0; - s0= s+s0; - s = s2+s1; - s2= s2-s1; - dst[0*4]= s0 + s; - dst[2*4]= s0 - s; - dst[1*4]= 2*s3 + s2; - dst[3*4]= s3 - 2*s2; - src++; - dst++; - } -} - -#if HAVE_MMX -static void dctB_mmx(DCTELEM *dst, DCTELEM *src){ - __asm__ volatile ( - "movq (%0), %%mm0 \n\t" - "movq 1*4*2(%0), %%mm1 \n\t" - "paddw 6*4*2(%0), %%mm0 \n\t" - "paddw 5*4*2(%0), %%mm1 \n\t" - "movq 2*4*2(%0), %%mm2 \n\t" - "movq 3*4*2(%0), %%mm3 \n\t" - "paddw 4*4*2(%0), %%mm2 \n\t" - "paddw %%mm3, %%mm3 \n\t" //s - "movq %%mm3, %%mm4 \n\t" //s - "psubw %%mm0, %%mm3 \n\t" //s-s0 - "paddw %%mm0, %%mm4 \n\t" //s+s0 - "movq %%mm2, %%mm0 \n\t" //s2 - "psubw %%mm1, %%mm2 \n\t" //s2-s1 - "paddw %%mm1, %%mm0 \n\t" //s2+s1 - "movq %%mm4, %%mm1 \n\t" //s0' - "psubw %%mm0, %%mm4 \n\t" //s0'-s' - "paddw %%mm0, %%mm1 \n\t" //s0'+s' - "movq %%mm3, %%mm0 \n\t" //s3' - "psubw %%mm2, %%mm3 \n\t" - "psubw %%mm2, %%mm3 \n\t" - "paddw %%mm0, %%mm2 \n\t" - "paddw %%mm0, %%mm2 \n\t" - "movq %%mm1, (%1) \n\t" - "movq %%mm4, 2*4*2(%1) \n\t" - "movq %%mm2, 1*4*2(%1) \n\t" - "movq %%mm3, 3*4*2(%1) \n\t" - :: "r" (src), "r"(dst) - ); -} -#endif - -static void (*dctB)(DCTELEM *dst, DCTELEM *src)= dctB_c; - -#define N0 4 -#define N1 5 -#define N2 10 -#define SN0 2 -#define SN1 2.2360679775 -#define SN2 3.16227766017 -#define N (1<<16) - -static const int factor[16]={ - N/(N0*N0), N/(N0*N1), N/(N0*N0),N/(N0*N2), - N/(N1*N0), N/(N1*N1), N/(N1*N0),N/(N1*N2), - N/(N0*N0), N/(N0*N1), N/(N0*N0),N/(N0*N2), - N/(N2*N0), N/(N2*N1), N/(N2*N0),N/(N2*N2), -}; - -static const int thres[16]={ - N/(SN0*SN0), N/(SN0*SN2), N/(SN0*SN0),N/(SN0*SN2), - N/(SN2*SN0), N/(SN2*SN2), N/(SN2*SN0),N/(SN2*SN2), - N/(SN0*SN0), N/(SN0*SN2), N/(SN0*SN0),N/(SN0*SN2), - N/(SN2*SN0), N/(SN2*SN2), N/(SN2*SN0),N/(SN2*SN2), -}; - -static int thres2[99][16]; - -static void init_thres2(void){ - int qp, i; - int bias= 0; //FIXME - - for(qp=0; qp<99; qp++){ - for(i=0; i<16; i++){ - thres2[qp][i]= ((i&1)?SN2:SN0) * ((i&4)?SN2:SN0) * XMAX(1,qp) * (1<<2) - 1 - bias; - } - } -} - -static int hardthresh_c(DCTELEM *src, int qp){ - int i; - int a; - - a= src[0] * factor[0]; - for(i=1; i<16; i++){ - unsigned int threshold1= thres2[qp][i]; - unsigned int threshold2= (threshold1<<1); - int level= src[i]; - if(((unsigned)(level+threshold1))>threshold2){ - a += level * factor[i]; - } - } - return (a + (1<<11))>>12; -} - -static int mediumthresh_c(DCTELEM *src, int qp){ - int i; - int a; - - a= src[0] * factor[0]; - for(i=1; i<16; i++){ - unsigned int threshold1= thres2[qp][i]; - unsigned int threshold2= (threshold1<<1); - int level= src[i]; - if(((unsigned)(level+threshold1))>threshold2){ - if(((unsigned)(level+2*threshold1))>2*threshold2){ - a += level * factor[i]; - }else{ - if(level>0) a+= 2*(level - (int)threshold1)*factor[i]; - else a+= 2*(level + (int)threshold1)*factor[i]; - } - } - } - return (a + (1<<11))>>12; -} - -static int softthresh_c(DCTELEM *src, int qp){ - int i; - int a; - - a= src[0] * factor[0]; - for(i=1; i<16; i++){ - unsigned int threshold1= thres2[qp][i]; - unsigned int threshold2= (threshold1<<1); - int level= src[i]; - if(((unsigned)(level+threshold1))>threshold2){ - if(level>0) a+= (level - (int)threshold1)*factor[i]; - else a+= (level + (int)threshold1)*factor[i]; - } - } - return (a + (1<<11))>>12; -} - -static int (*requantize)(DCTELEM *src, int qp)= hardthresh_c; - -static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, uint8_t *qp_store, int qp_stride, int is_luma){ - int x, y; - const int stride= is_luma ? p->temp_stride : ((width+16+15)&(~15)); - uint8_t *p_src= p->src + 8*stride; - DCTELEM *block= (DCTELEM *)p->src; - DCTELEM *temp= (DCTELEM *)(p->src + 32); - - if (!src || !dst) return; // HACK avoid crash for Y8 colourspace - for(y=0; yqp) - qp= p->qp; - else{ - qp= qp_store[ (XMIN(x, width-1)>>qps) + (XMIN(y, height-1)>>qps) * qp_stride]; - qp=norm_qscale(qp, p->mpeg2); - } - for(; x>6; - if((unsigned)v > 255) - v= (-v)>>31; - dst[x + y*dst_stride]= v; - } - } - } -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - int h= (height+16+15)&(~15); - - vf->priv->temp_stride= (width+16+15)&(~15); - vf->priv->src = av_malloc(vf->priv->temp_stride*(h+8)*sizeof(uint8_t)); - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi){ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - if(mpi->flags&MP_IMGFLAG_DIRECT){ - dmpi=vf->dmpi; - }else{ - // no DR, so get a new image! hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->width,mpi->height); - vf_clone_mpi_attributes(dmpi, mpi); - } - - vf->priv->mpeg2= mpi->qscale_type; - if(mpi->qscale || vf->priv->qp){ - filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, mpi->qscale, mpi->qstride, 1); - filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, mpi->qscale, mpi->qstride, 0); - filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, mpi->qscale, mpi->qstride, 0); - }else{ - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]); - memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]); - } - -#if HAVE_MMX - if(gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t"); -#endif -#if HAVE_MMX2 - if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t"); -#endif - - return vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf){ - if(!vf->priv) return; - - av_free(vf->priv->src); - vf->priv->src= NULL; - - free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf,fmt); - } - return 0; -} - -static int control(struct vf_instance *vf, int request, void* data){ - return vf_next_control(vf,request,data); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->control= control; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - if (args) sscanf(args, "%d:%d", &vf->priv->qp, &vf->priv->mode); - - if(vf->priv->qp < 0) - vf->priv->qp = 0; - - init_thres2(); - - switch(vf->priv->mode){ - case 0: requantize= hardthresh_c; break; - case 1: requantize= softthresh_c; break; - default: - case 2: requantize= mediumthresh_c; break; - } - -#if HAVE_MMX - if(gCpuCaps.hasMMX){ - dctB= dctB_mmx; - } -#endif -#if 0 - if(gCpuCaps.hasMMX){ - switch(vf->priv->mode){ - case 0: requantize= hardthresh_mmx; break; - case 1: requantize= softthresh_mmx; break; - } - } -#endif - - return 1; -} - -const vf_info_t vf_info_pp7 = { - "postprocess 7", - "pp7", - "Michael Niedermayer", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_qp.c b/libmpcodecs/vf_qp.c deleted file mode 100644 index 64e62723d8..0000000000 --- a/libmpcodecs/vf_qp.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2004 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include - -#include -#include - -#include "mp_msg.h" -#include "cpudetect.h" -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libvo/fastmemcpy.h" - - -struct vf_priv_s { - char eq[200]; - int8_t *qp; - int8_t lut[257]; - int qp_stride; -}; - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - int h= (height+15)>>4; - int i; - - vf->priv->qp_stride= (width+15)>>4; - vf->priv->qp= av_malloc(vf->priv->qp_stride*h*sizeof(int8_t)); - - for(i=-129; i<128; i++){ - double const_values[]={ - M_PI, - M_E, - i != -129, - i, - 0 - }; - const char * const const_names[]={ - "PI", - "E", - "known", - "qp", - NULL - }; - double temp_val; - int res; - - res= av_expr_parse_and_eval(&temp_val, vf->priv->eq, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, NULL); - - if (res < 0){ - mp_msg(MSGT_VFILTER, MSGL_ERR, "qp: Error evaluating \"%s\" \n", vf->priv->eq); - return 0; - } - vf->priv->lut[i+129]= lrintf(temp_val); - } - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi){ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags, mpi->w, mpi->h); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - int x,y; - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // no DR, so get a new image! hope we'll get DR buffer: - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->w,mpi->h); - } - - dmpi= vf->dmpi; - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]); - if(mpi->flags&MP_IMGFLAG_PLANAR){ - memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]); - } - } - vf_clone_mpi_attributes(dmpi, mpi); - - dmpi->qscale = vf->priv->qp; - dmpi->qstride= vf->priv->qp_stride; - if(mpi->qscale){ - for(y=0; y<((dmpi->h+15)>>4); y++){ - for(x=0; xpriv->qp_stride; x++){ - dmpi->qscale[x + dmpi->qstride*y]= - vf->priv->lut[ 129 + ((int8_t)mpi->qscale[x + mpi->qstride*y]) ]; - } - } - }else{ - int qp= vf->priv->lut[0]; - for(y=0; y<((dmpi->h+15)>>4); y++){ - for(x=0; xpriv->qp_stride; x++){ - dmpi->qscale[x + dmpi->qstride*y]= qp; - } - } - } - - return vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf){ - if(!vf->priv) return; - - av_free(vf->priv->qp); - vf->priv->qp= NULL; - - av_free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->uninit=uninit; - vf->priv=av_malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - -// avcodec_init(); - - if (args) strncpy(vf->priv->eq, args, 199); - - return 1; -} - -const vf_info_t vf_info_qp = { - "QP changer", - "qp", - "Michael Niedermayer", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_remove_logo.c b/libmpcodecs/vf_remove_logo.c deleted file mode 100644 index 1270f5e6c9..0000000000 --- a/libmpcodecs/vf_remove_logo.c +++ /dev/null @@ -1,908 +0,0 @@ -/* - * This filter loads a .pgm mask file showing where a logo is and uses - * a blur transform to remove the logo. - * - * Copyright (C) 2005 Robert Edele - * - * This file is part of MPlayer. - * - * 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. - */ - -/** - * \file vf_remove_logo.c - * - * \brief Advanced blur-based logo removing filter. - - * Hello and welcome. This code implements a filter to remove annoying TV - * logos and other annoying images placed onto a video stream. It works by filling - * in the pixels that comprise the logo with neighboring pixels. The transform is - * very loosely based on a gaussian blur, but it is different enough to merit its - * own paragraph later on. It is a major improvement on the old delogo filter as - * it both uses a better blurring algorithm and uses a bitmap to use an arbitrary - * and generally much tighter fitting shape than a rectangle. - * - * The filter requires 1 argument and has no optional arguments. It requires - * a filter bitmap, which must be in PGM or PPM format. A sample invocation would - * be -vf remove_logo=/home/username/logo_bitmaps/xyz.pgm. Pixels with a value of - * zero are not part of the logo, and non-zero pixels are part of the logo. If you - * use white (255) for the logo and black (0) for the rest, you will be safe. For - * making the filter bitmap, I recommend taking a screen capture of a black frame - * with the logo visible, and then using The GIMP's threshold filter followed by - * the erode filter once or twice. If needed, little splotches can be fixed - * manually. Remember that if logo pixels are not covered, the filter quality will - * be much reduced. Marking too many pixels as part of the logo doesn't hurt as - * much, but it will increase the amount of blurring needed to cover over the - * image and will destroy more information than necessary. Additionally, this blur - * algorithm is O(n) = n^4, where n is the width and height of a hypothetical - * square logo, so extra pixels will slow things down on a large lo - * - * The logo removal algorithm has two key points. The first is that it - * distinguishes between pixels in the logo and those not in the logo by using the - * passed-in bitmap. Pixels not in the logo are copied over directly without being - * modified and they also serve as source pixels for the logo fill-in. Pixels - * inside the logo have the mask applied. - * - * At init-time the bitmap is reprocessed internally, and the distance to the - * nearest edge of the logo (Manhattan distance), along with a little extra to - * remove rough edges, is stored in each pixel. This is done using an in-place - * erosion algorithm, and incrementing each pixel that survives any given erosion. - * Once every pixel is eroded, the maximum value is recorded, and a set of masks - * from size 0 to this size are generaged. The masks are circular binary masks, - * where each pixel within a radius N (where N is the size of the mask) is a 1, - * and all other pixels are a 0. Although a gaussian mask would be more - * mathematically accurate, a binary mask works better in practice because we - * generally do not use the central pixels in the mask (because they are in the - * logo region), and thus a gaussian mask will cause too little blur and thus a - * very unstable image. - * - * The mask is applied in a special way. Namely, only pixels in the mask that - * line up to pixels outside the logo are used. The dynamic mask size means that - * the mask is just big enough so that the edges touch pixels outside the logo, so - * the blurring is kept to a minimum and at least the first boundary condition is - * met (that the image function itself is continuous), even if the second boundary - * condition (that the derivative of the image function is continuous) is not met. - * A masking algorithm that does preserve the second boundary coundition - * (perhaps something based on a highly-modified bi-cubic algorithm) should offer - * even better results on paper, but the noise in a typical TV signal should make - * anything based on derivatives hopelessly noisy. - */ - -#include -#include -#include -#include -#include - -#include "osdep/io.h" - -#include "config.h" -#include "mp_msg.h" -#include "libvo/fastmemcpy.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -//===========================================================================// - -/** \brief Returns the larger of the two arguments. **/ -#define max(x,y) ((x)>(y)?(x):(y)) -/** \brief Returns the smaller of the two arguments. **/ -#define min(x,y) ((x)>(y)?(y):(x)) - -/** - * \brief Test if a pixel is part of the logo. - */ -#define test_filter(image, x, y) ((unsigned char) (image->pixel[((y) * image->width) + (x)])) - -/** - * \brief Chooses a slightly larger mask size to improve performance. - * - * This function maps the absolute minimum mask size needed to the mask size we'll - * actually use. f(x) = x (the smallest that will work) will produce the sharpest - * results, but will be quite jittery. f(x) = 1.25x (what I'm using) is a good - * tradeoff in my opinion. This will calculate only at init-time, so you can put a - * long expression here without effecting performance. - */ -#define apply_mask_fudge_factor(x) (((x) >> 2) + x) - -/** - * \brief Simple implementation of the PGM image format. - * - * This struct holds a bare-bones image loaded from a PGM or PPM file. Once - * loaded and pre-processed, each pixel in this struct will contain how far from - * the edge of the logo each pixel is, using the manhattan distance (|dx| + |dy|). - * - * pixels in char * pixel can be addressed using (y * width) + height. - */ -typedef struct -{ - unsigned int width; - unsigned int height; - - unsigned char * pixel; - -} pgm_structure; - -/** - * \brief Stores persistant variables. - * - * Variables stored here are kept from frame to frame, and separate instances of - * the filter will get their own separate copies. - */ -struct vf_priv_s -{ - unsigned int fmt; /* Not exactly sure of the use for this. It came with the example filter I used as a basis for this, and it looks like a lot of stuff will break if I remove it. */ - int max_mask_size; /* The largest possible mask size that will be needed with the given filter and corresponding half_size_filter. The half_size_filter can have a larger requirment in some rare (but not degenerate) cases. */ - int * * * mask; /* Stores our collection of masks. The first * is for an array of masks, the second for the y axis, and the third for the x axis. */ - pgm_structure * filter; /* Stores the full-size filter image. This is used to tell what pixels are in the logo or not in the luma plane. */ - pgm_structure * half_size_filter; /* Stores a 50% width and 50% height filter image. This is used to tell what pixels are in the logo or not in the chroma planes. */ - /* These 8 variables store the bounding rectangles that the logo resides in. */ - int bounding_rectangle_posx1; - int bounding_rectangle_posy1; - int bounding_rectangle_posx2; - int bounding_rectangle_posy2; - int bounding_rectangle_half_size_posx1; - int bounding_rectangle_half_size_posy1; - int bounding_rectangle_half_size_posx2; - int bounding_rectangle_half_size_posy2; -} vf_priv_s; - -/** - * \brief Mallocs memory and checks to make sure it succeeded. - * - * \param size How many bytes to allocate. - * - * \return A pointer to the freshly allocated memory block, or NULL on failutre. - * - * Mallocs memory, and checks to make sure it was successfully allocated. Because - * of how MPlayer works, it cannot safely halt execution, but at least the user - * will get an error message before the segfault happens. - */ -static void * safe_malloc(int size) -{ - void * answer = malloc(size); - if (answer == NULL) - mp_msg(MSGT_VFILTER, MSGL_ERR, "Unable to allocate memory in vf_remove_logo.c\n"); - - return answer; -} - -/** - * \brief Calculates the smallest rectangle that will encompass the logo region. - * - * \param filter This image contains the logo around which the rectangle will - * will be fitted. - * - * The bounding rectangle is calculated by testing successive lines (from the four - * sides of the rectangle) until no more can be removed without removing logo - * pixels. The results are returned by reference to posx1, posy1, posx2, and - * posy2. - */ -static void calculate_bounding_rectangle(int * posx1, int * posy1, int * posx2, int * posy2, pgm_structure * filter) -{ - int x; /* Temporary variables to run */ - int y; /* through each row or column. */ - int start_x; - int start_y; - int end_x = filter->width - 1; - int end_y = filter->height - 1; - int did_we_find_a_logo_pixel = 0; - - /* Let's find the top bound first. */ - for (start_x = 0; start_x < filter->width && !did_we_find_a_logo_pixel; start_x++) - { - for (y = 0; y < filter->height; y++) - { - did_we_find_a_logo_pixel |= test_filter(filter, start_x, y); - } - } - start_x--; - - /* Now the bottom bound. */ - did_we_find_a_logo_pixel = 0; - for (end_x = filter->width - 1; end_x > start_x && !did_we_find_a_logo_pixel; end_x--) - { - for (y = 0; y < filter->height; y++) - { - did_we_find_a_logo_pixel |= test_filter(filter, end_x, y); - } - } - end_x++; - - /* Left bound. */ - did_we_find_a_logo_pixel = 0; - for (start_y = 0; start_y < filter->height && !did_we_find_a_logo_pixel; start_y++) - { - for (x = 0; x < filter->width; x++) - { - did_we_find_a_logo_pixel |= test_filter(filter, x, start_y); - } - } - start_y--; - - /* Right bound. */ - did_we_find_a_logo_pixel = 0; - for (end_y = filter->height - 1; end_y > start_y && !did_we_find_a_logo_pixel; end_y--) - { - for (x = 0; x < filter->width; x++) - { - did_we_find_a_logo_pixel |= test_filter(filter, x, end_y); - } - } - end_y++; - - *posx1 = start_x; - *posy1 = start_y; - *posx2 = end_x; - *posy2 = end_y; - - return; -} - -/** - * \brief Free mask memory. - * - * \param vf Data structure which stores our persistant data, and is to be freed. - * - * We call this function when our filter is done. It will free the memory - * allocated to the masks and leave the variables in a safe state. - */ -static void destroy_masks(vf_instance_t * vf) -{ - int a, b; - - /* Load values from the vf->priv struct for faster dereferencing. */ - int * * * mask = vf->priv->mask; - int max_mask_size = vf->priv->max_mask_size; - - if (mask == NULL) - return; /* Nothing allocated, so return before we segfault. */ - - /* Free all allocated memory. */ - for (a = 0; a <= max_mask_size; a++) /* Loop through each mask. */ - { - for (b = -a; b <= a; b++) /* Loop through each scanline in a mask. */ - { - free(mask[a][b + a]); /* Free a scanline. */ - } - free(mask[a]); /* Free a mask. */ - } - free(mask); /* Free the array of pointers pointing to the masks. */ - - /* Set the pointer to NULL, so that any duplicate calls to this function will not cause a crash. */ - vf->priv->mask = NULL; - - return; -} - -/** - * \brief Set up our array of masks. - * - * \param vf Where our filter stores persistance data, like these masks. - * - * This creates an array of progressively larger masks and calculates their - * values. The values will not change during program execution once this function - * is done. - */ -static void initialize_masks(vf_instance_t * vf) -{ - int a, b, c; - - /* Load values from the vf->priv struct for faster dereferencing. */ - int * * * mask = vf->priv->mask; - int max_mask_size = vf->priv->max_mask_size; /* This tells us how many masks we'll need to generate. */ - - /* Create a circular mask for each size up to max_mask_size. When the filter is applied, the mask size is - determined on a pixel by pixel basis, with pixels nearer the edge of the logo getting smaller mask sizes. */ - mask = (int * * *) safe_malloc(sizeof(int * *) * (max_mask_size + 1)); - for (a = 0; a <= max_mask_size; a++) - { - mask[a] = (int * *) safe_malloc(sizeof(int *) * ((a * 2) + 1)); - for (b = -a; b <= a; b++) - { - mask[a][b + a] = (int *) safe_malloc(sizeof(int) * ((a * 2) + 1)); - for (c = -a; c <= a; c++) - { - if ((b * b) + (c * c) <= (a * a)) /* Circular 0/1 mask. */ - mask[a][b + a][c + a] = 1; - else - mask[a][b + a][c + a] = 0; - } - } - } - - /* Store values back to vf->priv so they aren't lost after the function returns. */ - vf->priv->mask = mask; - - return; -} - -/** - * \brief Pre-processes an image to give distance information. - * - * \param vf Data structure that holds persistant information. All it is used for - in this function is to store the calculated max_mask_size variable. - * \param mask This image will be converted from a greyscale image into a - * distance image. - * - * This function takes a greyscale image (pgm_structure * mask) and converts it - * in place into a distance image. A distance image is zero for pixels ourside of - * the logo and is the manhattan distance (|dx| + |dy|) for pixels inside of the - * logo. This will overestimate the distance, but that is safe, and is far easier - * to implement than a proper pythagorean distance since I'm using a modified - * erosion algorithm to compute the distances. - */ -static void convert_mask_to_strength_mask(vf_instance_t * vf, pgm_structure * mask) -{ - int x, y; /* Used by our for loops to go through every single pixel in the picture one at a time. */ - int has_anything_changed = 1; /* Used by the main while() loop to know if anything changed on the last erosion. */ - int current_pass = 0; /* How many times we've gone through the loop. Used in the in-place erosion algorithm - and to get us max_mask_size later on. */ - int max_mask_size; /* This will record how large a mask the pixel that is the furthest from the edge of the logo - (and thus the neediest) is. */ - char * current_pixel = mask->pixel; /* This stores the actual pixel data. */ - - /* First pass, set all non-zero values to 1. After this loop finishes, the data should be considered numeric - data for the filter, not color data. */ - for (x = 0; x < mask->height * mask->width; x++, current_pixel++) - if(*current_pixel) *current_pixel = 1; - - /* Second pass and future passes. For each pass, if a pixel is itself the same value as the current pass, - and its four neighbors are too, then it is incremented. If no pixels are incremented by the end of the pass, - then we go again. Edge pixels are counted as always excluded (this should be true anyway for any sane mask, - but if it isn't this will ensure that we eventually exit). */ - while (has_anything_changed) - { - current_pass++; - current_pixel = mask->pixel; - - has_anything_changed = 0; /* If this doesn't get set by the end of this pass, then we're done. */ - - for (y = 1; y < mask->height - 1; y++) - { - for (x = 1; x < mask->width - 1; x++) - { - /* Apply the in-place erosion transform. It is based on the following two premises: 1 - Any pixel that fails 1 erosion - will fail all future erosions. 2 - Only pixels having survived all erosions up to the present will be >= to - current_pass. It doesn't matter if it survived the current pass, failed it, or hasn't been tested yet. */ - if (*current_pixel >= current_pass && /* By using >= instead of ==, we allow the algorithm to work in place. */ - *(current_pixel + 1) >= current_pass && - *(current_pixel - 1) >= current_pass && - *(current_pixel + mask->width) >= current_pass && - *(current_pixel - mask->width) >= current_pass) - { - (*current_pixel)++; /* Increment the value since it still has not been eroded, as evidenced by the if statement - that just evaluated to true. */ - has_anything_changed = 1; - } - current_pixel++; - } - } - } - - /* Apply the fudge factor, which will increase the size of the mask a little to reduce jitter at the cost of more blur. */ - for (y = 1; y < mask->height - 1; y++) - { - for (x = 1; x < mask->width - 1; x++) - { - mask->pixel[(y * mask->width) + x] = apply_mask_fudge_factor(mask->pixel[(y * mask->width) + x]); - } - } - - max_mask_size = current_pass + 1; /* As a side-effect, we now know the maximum mask size, which we'll use to generate our masks. */ - max_mask_size = apply_mask_fudge_factor(max_mask_size); /* Apply the fudge factor to this number too, since we must - ensure that enough masks are generated. */ - vf->priv->max_mask_size = max_mask_size; /* Commit the newly calculated max_mask_size to the vf->priv struct. */ - - return; -} - -/** - * \brief Our blurring function. - * - * \param vf Stores persistant data. In this function we are interested in the - * array of masks. - * \param value_out The properly blurred and delogoed pixel is outputted here. - * \param logo_mask Tells us which pixels are in the logo and which aren't. - * \param image The image that is having its logo removed. - * \param x x-coordinate of the pixel to blur. - * \param y y-coordinate of the pixel to blur. - * \param plane 0 = luma, 1 = blue chroma, 2 = red chroma (YUV). - * - * This function is the core of the filter. It takes a pixel that is inside the - * logo and blurs it. It does so by finding the average of all the pixels within - * the mask and outside of the logo. - */ -static void get_blur(const vf_instance_t * const vf, unsigned int * const value_out, const pgm_structure * const logo_mask, - const mp_image_t * const image, const int x, const int y, const int plane) -{ - int mask_size; /* Mask size tells how large a circle to use. The radius is about (slightly larger than) mask size. */ - /* Get values from vf->priv for faster dereferencing. */ - int * * * mask = vf->priv->mask; - - int start_posx, start_posy, end_posx, end_posy; - int i, j; - unsigned int accumulator = 0, divisor = 0; - const unsigned char * mask_read_position; /* What pixel we are reading out of the circular blur mask. */ - const unsigned char * logo_mask_read_position; /* What pixel we are reading out of the filter image. */ - - /* Prepare our bounding rectangle and clip it if need be. */ - mask_size = test_filter(logo_mask, x, y); - start_posx = max(0, x - mask_size); - start_posy = max(0, y - mask_size); - end_posx = min(image->width - 1, x + mask_size); - end_posy = min(image->height - 1, y + mask_size); - - mask_read_position = image->planes[plane] + (image->stride[plane] * start_posy) + start_posx; - logo_mask_read_position = logo_mask->pixel + (start_posy * logo_mask->width) + start_posx; - - for (j = start_posy; j <= end_posy; j++) - { - for (i = start_posx; i <= end_posx; i++) - { - if (!(*logo_mask_read_position) && mask[mask_size][i - start_posx][j - start_posy]) - { /* Check to see if this pixel is in the logo or not. Only use the pixel if it is not. */ - accumulator += *mask_read_position; - divisor++; - } - - mask_read_position++; - logo_mask_read_position++; - } - - mask_read_position += (image->stride[plane] - ((end_posx + 1) - start_posx)); - logo_mask_read_position += (logo_mask->width - ((end_posx + 1) - start_posx)); - } - - if (divisor == 0) /* This means that not a single pixel is outside of the logo, so we have no data. */ - { /* We should put some eye catching value here, to indicate the flaw to the user. */ - *value_out = 255; - } - else /* Else we need to normalise the data using the divisor. */ - { - *value_out = (accumulator + (divisor / 2)) / divisor; /* Divide, taking into account average rounding error. */ - } - - return; -} - -/** - * \brief Free a pgm_structure. Undoes load_pgm(...). - */ -static void destroy_pgm(pgm_structure * to_be_destroyed) -{ - if (to_be_destroyed == NULL) - return; /* Don't do anything if a NULL pointer was passed it. */ - - /* Internally allocated memory. */ - if (to_be_destroyed->pixel != NULL) - { - free(to_be_destroyed->pixel); - to_be_destroyed->pixel = NULL; - } - - /* Free the actual struct instance. This is done here and not by the calling function. */ - free(to_be_destroyed); -} - -/** \brief Helper function for load_pgm(...) to skip whitespace. */ -static void load_pgm_skip(FILE *f) { - int c, comment = 0; - do { - c = fgetc(f); - if (c == '#') - comment = 1; - if (c == '\n') - comment = 0; - } while (c != EOF && (isspace(c) || comment)); - ungetc(c, f); -} - -#define REMOVE_LOGO_LOAD_PGM_ERROR_MESSAGE(message) {mp_msg(MSGT_VFILTER, MSGL_ERR, message); return NULL;} - -/** - * \brief Loads a raw pgm or ppm file into a newly created pgm_structure object. - * - * \param file_name The name of the file to be loaded. So long as the file is a - * valid pgm or ppm file, it will load correctly, even if the - * extension is missing or invalid. - * - * \return A pointer to the newly created pgm_structure object. Don't forget to - * call destroy_pgm(...) when you're done with this. If an error occurs, - * NULL is returned. - * - * Can load either raw pgm (P5) or raw ppm (P6) image files as a binary image. - * While a pgm file will be loaded normally (greyscale), the only thing that is - * guaranteed with ppm is that all zero (R = 0, G = 0, B = 0) pixels will remain - * zero, and non-zero pixels will remain non-zero. - */ -static pgm_structure * load_pgm(const char * file_name) -{ - int maximum_greyscale_value; - FILE * input; - int pnm_number; - pgm_structure * new_pgm = (pgm_structure *) safe_malloc (sizeof(pgm_structure)); - char * write_position; - char * end_position; - int image_size; /* width * height */ - - if((input = fopen(file_name, "rb")) == NULL) REMOVE_LOGO_LOAD_PGM_ERROR_MESSAGE("[vf]remove-logo: Unable to open file. File not found or insufficient permissions.\n"); - - /* Parse the PGM header. */ - if (fgetc(input) != 'P') REMOVE_LOGO_LOAD_PGM_ERROR_MESSAGE("[vf]remove-logo: File is not a valid PGM or PPM file.\n"); - pnm_number = fgetc(input) - '0'; - if (pnm_number != 5 && pnm_number != 6) REMOVE_LOGO_LOAD_PGM_ERROR_MESSAGE("[vf]remove-logo: Invalid PNM file. Only raw PGM (Portable Gray Map) and raw PPM (Portable Pixel Map) subtypes are allowed.\n"); - load_pgm_skip(input); - if (fscanf(input, "%i", &(new_pgm->width)) != 1) REMOVE_LOGO_LOAD_PGM_ERROR_MESSAGE("[vf]remove-logo: Invalid PGM/PPM header.\n"); - load_pgm_skip(input); - if (fscanf(input, "%i", &(new_pgm->height)) != 1) REMOVE_LOGO_LOAD_PGM_ERROR_MESSAGE("[vf]remove-logo: Invalid PGM/PPM header.\n"); - load_pgm_skip(input); - if (fscanf(input, "%i", &maximum_greyscale_value) != 1) REMOVE_LOGO_LOAD_PGM_ERROR_MESSAGE("[vf]remove-logo: Invalid PGM/PPM header.\n"); - if (maximum_greyscale_value >= 256) REMOVE_LOGO_LOAD_PGM_ERROR_MESSAGE("[vf]remove_logo: Only 1 byte per pixel (pgm) or 1 byte per color value (ppm) are supported.\n"); - load_pgm_skip(input); - - new_pgm->pixel = (unsigned char *) safe_malloc (sizeof(unsigned char) * new_pgm->width * new_pgm->height); - - /* Load the pixels. */ - /* Note: I am aware that fgetc(input) isn't the fastest way of doing things, but it is quite compact and the code only runs once when the filter is initialized.*/ - image_size = new_pgm->width * new_pgm->height; - end_position = new_pgm->pixel + image_size; - for (write_position = new_pgm->pixel; write_position < end_position; write_position++) - { - *write_position = fgetc(input); - if (pnm_number == 6) /* This tests to see if the file is a PPM file. */ - { /* If it is, then consider the pixel set if any of the three color channels are set. Since we just care about == 0 or != 0, a bitwise or will do the trick. */ - *write_position |= fgetc(input); - *write_position |= fgetc(input); - } - } - - return new_pgm; -} - -/** - * \brief Generates a scaled down image with half width, height, and intensity. - * - * \param vf Our struct for persistant data. In this case, it is used to update - * mask_max_size with the larger of the old or new value. - * \param input_image The image from which the new half-sized one will be based. - * - * \return The newly allocated and shrunken image. - * - * This function not only scales down an image, but halves the value in each pixel - * too. The purpose of this is to produce a chroma filter image out of a luma - * filter image. The pixel values store the distance to the edge of the logo and - * halving the dimensions halves the distance. This function rounds up, because - * a downwards rounding error could cause the filter to fail, but an upwards - * rounding error will only cause a minor amount of excess blur in the chroma - * planes. - */ -static pgm_structure * generate_half_size_image(vf_instance_t * vf, pgm_structure * input_image) -{ - int x, y; - pgm_structure * new_pgm = (pgm_structure *) safe_malloc (sizeof(pgm_structure)); - int has_anything_changed = 1; - int current_pass; - int max_mask_size; - char * current_pixel; - - new_pgm->width = input_image->width / 2; - new_pgm->height = input_image->height / 2; - new_pgm->pixel = (unsigned char *) safe_malloc (sizeof(unsigned char) * new_pgm->width * new_pgm->height); - - /* Copy over the image data, using the average of 4 pixels for to calculate each downsampled pixel. */ - for (y = 0; y < new_pgm->height; y++) - for (x = 0; x < new_pgm->width; x++) - { - /* Set the pixel if there exists a non-zero value in the source pixels, else clear it. */ - new_pgm->pixel[(y * new_pgm->width) + x] = input_image->pixel[((y << 1) * input_image->width) + (x << 1)] || - input_image->pixel[((y << 1) * input_image->width) + (x << 1) + 1] || - input_image->pixel[(((y << 1) + 1) * input_image->width) + (x << 1)] || - input_image->pixel[(((y << 1) + 1) * input_image->width) + (x << 1) + 1]; - new_pgm->pixel[(y * new_pgm->width) + x] = min(1, new_pgm->pixel[(y * new_pgm->width) + x]); - } - - /* Now we need to recalculate the numbers for the smaller size. Just using the old_value / 2 can cause subtle - and fairly rare, but very nasty, bugs. */ - - current_pixel = new_pgm->pixel; - /* First pass, set all non-zero values to 1. */ - for (x = 0; x < new_pgm->height * new_pgm->width; x++, current_pixel++) - if(*current_pixel) *current_pixel = 1; - - /* Second pass and future passes. For each pass, if a pixel is itself the same value as the current pass, - and its four neighbors are too, then it is incremented. If no pixels are incremented by the end of the pass, - then we go again. Edge pixels are counted as always excluded (this should be true anyway for any sane mask, - but if it isn't this will ensure that we eventually exit). */ - current_pass = 0; - while (has_anything_changed) - { - current_pass++; - - has_anything_changed = 0; /* If this doesn't get set by the end of this pass, then we're done. */ - - for (y = 1; y < new_pgm->height - 1; y++) - { - for (x = 1; x < new_pgm->width - 1; x++) - { - if (new_pgm->pixel[(y * new_pgm->width) + x] >= current_pass && /* By using >= instead of ==, we allow the algorithm to work in place. */ - new_pgm->pixel[(y * new_pgm->width) + (x + 1)] >= current_pass && - new_pgm->pixel[(y * new_pgm->width) + (x - 1)] >= current_pass && - new_pgm->pixel[((y + 1) * new_pgm->width) + x] >= current_pass && - new_pgm->pixel[((y - 1) * new_pgm->width) + x] >= current_pass) - { - new_pgm->pixel[(y * new_pgm->width) + x]++; /* Increment the value since it still has not been eroded, - as evidenced by the if statement that just evaluated to true. */ - has_anything_changed = 1; - } - } - } - } - - for (y = 1; y < new_pgm->height - 1; y++) - { - for (x = 1; x < new_pgm->width - 1; x++) - { - new_pgm->pixel[(y * new_pgm->width) + x] = apply_mask_fudge_factor(new_pgm->pixel[(y * new_pgm->width) + x]); - } - } - - max_mask_size = current_pass + 1; /* As a side-effect, we now know the maximum mask size, which we'll use to generate our masks. */ - max_mask_size = apply_mask_fudge_factor(max_mask_size); - /* Commit the newly calculated max_mask_size to the vf->priv struct. */ - vf->priv->max_mask_size = max(max_mask_size, vf->priv->max_mask_size); - - return new_pgm; -} - -/** - * \brief Checks if YV12 is supported by the next filter. - */ -static unsigned int find_best(struct vf_instance *vf){ - int is_format_okay = vf->next->query_format(vf->next, IMGFMT_YV12); - if ((is_format_okay & VFCAP_CSP_SUPPORTED_BY_HW) || (is_format_okay & VFCAP_CSP_SUPPORTED)) - return IMGFMT_YV12; - else - return 0; -} - -//===========================================================================// - -/** - * \brief Configure the filter and call the next filter's config function. - */ -static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt) -{ - if(!(vf->priv->fmt=find_best(vf))) - return 0; - else - return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt); -} - -/** - * \brief Removes the logo from a plane (either luma or chroma). - * - * \param vf Not needed by this function, but needed by the blur function. - * \param source The image to have it's logo removed. - * \param destination Where the output image will be stored. - * \param source_stride How far apart (in memory) two consecutive lines are. - * \param destination Same as source_stride, but for the destination image. - * \param width Width of the image. This is the same for source and destination. - * \param height Height of the image. This is the same for source and destination. - * \param is_image_direct If the image is direct, then source and destination are - * the same and we can save a lot of time by not copying pixels that - * haven't changed. - * \param filter The image that stores the distance to the edge of the logo for - * each pixel. - * \param logo_start_x Smallest x-coordinate that contains at least 1 logo pixel. - * \param logo_start_y Smallest y-coordinate that contains at least 1 logo pixel. - * \param logo_end_x Largest x-coordinate that contains at least 1 logo pixel. - * \param logo_end_y Largest y-coordinate that contains at least 1 logo pixel. - * - * This function processes an entire plane. Pixels outside of the logo are copied - * to the output without change, and pixels inside the logo have the de-blurring - * function applied. - */ -static void convert_yv12(const vf_instance_t * const vf, const char * const source, const int source_stride, - const mp_image_t * const source_image, const int width, const int height, - char * const destination, const int destination_stride, int is_image_direct, pgm_structure * filter, - const int plane, const int logo_start_x, const int logo_start_y, const int logo_end_x, const int logo_end_y) -{ - int y; - int x; - - /* These pointers point to where we are getting our pixel data (inside mpi) and where we are storing it (inside dmpi). */ - const unsigned char * source_line; - unsigned char * destination_line; - - if (!is_image_direct) - memcpy_pic(destination, source, width, height, destination_stride, source_stride); - - for (y = logo_start_y; y <= logo_end_y; y++) - { - source_line = (const unsigned char *) source + (source_stride * y); - destination_line = (unsigned char *) destination + (destination_stride * y); - - for (x = logo_start_x; x <= logo_end_x; x++) - { - unsigned int output; - - if (filter->pixel[(y * filter->width) + x]) /* Only process if we are in the logo. */ - { - get_blur(vf, &output, filter, source_image, x, y, plane); - destination_line[x] = output; - } - else /* Else just copy the data. */ - if (!is_image_direct) - destination_line[x] = source_line[x]; - } - } -} - -/** - * \brief Process a frame. - * - * \param mpi The image sent to use by the previous filter. - * \param dmpi Where we will store the processed output image. - * \param vf This is how the filter gets access to it's persistant data. - * - * \return The return code of the next filter, or 0 on failure/error. - * - * This function processes an entire frame. The frame is sent by the previous - * filter, has the logo removed by the filter, and is then sent to the next - * filter. - */ -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - dmpi=vf_get_image(vf->next,vf->priv->fmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w, mpi->h); - - /* Check to make sure that the filter image and the video stream are the same size. */ - if (vf->priv->filter->width != mpi->w || vf->priv->filter->height != mpi->h) - { - mp_msg(MSGT_VFILTER,MSGL_ERR, "Filter image and video stream are not of the same size. (Filter: %d x %d, Stream: %d x %d)\n", - vf->priv->filter->width, vf->priv->filter->height, mpi->w, mpi->h); - return 0; - } - - switch(dmpi->imgfmt){ - case IMGFMT_YV12: - convert_yv12(vf, mpi->planes[0], mpi->stride[0], mpi, mpi->w, mpi->h, - dmpi->planes[0], dmpi->stride[0], - mpi->flags & MP_IMGFLAG_DIRECT, vf->priv->filter, 0, - vf->priv->bounding_rectangle_posx1, vf->priv->bounding_rectangle_posy1, - vf->priv->bounding_rectangle_posx2, vf->priv->bounding_rectangle_posy2); - convert_yv12(vf, mpi->planes[1], mpi->stride[1], mpi, mpi->w / 2, mpi->h / 2, - dmpi->planes[1], dmpi->stride[1], - mpi->flags & MP_IMGFLAG_DIRECT, vf->priv->half_size_filter, 1, - vf->priv->bounding_rectangle_half_size_posx1, vf->priv->bounding_rectangle_half_size_posy1, - vf->priv->bounding_rectangle_half_size_posx2, vf->priv->bounding_rectangle_half_size_posy2); - convert_yv12(vf, mpi->planes[2], mpi->stride[2], mpi, mpi->w / 2, mpi->h / 2, - dmpi->planes[2], dmpi->stride[2], - mpi->flags & MP_IMGFLAG_DIRECT, vf->priv->half_size_filter, 2, - vf->priv->bounding_rectangle_half_size_posx1, vf->priv->bounding_rectangle_half_size_posy1, - vf->priv->bounding_rectangle_half_size_posx2, vf->priv->bounding_rectangle_half_size_posy2); - break; - - default: - mp_msg(MSGT_VFILTER,MSGL_ERR,"Unhandled format: 0x%X\n",dmpi->imgfmt); - return 0; - } - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -/** - * \brief Checks to see if the next filter accepts YV12 images. - */ -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - if (fmt == IMGFMT_YV12) - return vf->next->query_format(vf->next, IMGFMT_YV12); - else - return 0; -} - -/** - * \brief Frees memory that our filter allocated. - * - * This is called at exit-time. - */ -static void uninit(vf_instance_t *vf) -{ - /* Destroy our masks and images. */ - destroy_pgm(vf->priv->filter); - destroy_pgm(vf->priv->half_size_filter); - destroy_masks(vf); - - /* Destroy our private structure that had been used to store those masks and images. */ - free(vf->priv); - - return; -} - -/** - * \brief Initializes our filter. - * - * \param args The arguments passed in from the command line go here. This - * filter expects only a single argument telling it where the PGM - * or PPM file that describes the logo region is. - * - * This sets up our instance variables and parses the arguments to the filter. - */ -static int vf_open(vf_instance_t *vf, char *args) -{ - vf->priv = safe_malloc(sizeof(vf_priv_s)); - vf->uninit = uninit; - - /* Load our filter image. */ - if (args) - vf->priv->filter = load_pgm(args); - else - { - mp_msg(MSGT_VFILTER, MSGL_ERR, "[vf]remove_logo usage: remove_logo=/path/to/filter_image_file.pgm\n"); - free(vf->priv); - return 0; - } - - if (vf->priv->filter == NULL) - { - /* Error message was displayed by load_pgm(). */ - free(vf->priv); - return 0; - } - - /* Create the scaled down filter image for the chroma planes. */ - convert_mask_to_strength_mask(vf, vf->priv->filter); - vf->priv->half_size_filter = generate_half_size_image(vf, vf->priv->filter); - - /* Now that we know how many masks we need (the info is in vf), we can generate the masks. */ - initialize_masks(vf); - - /* Calculate our bounding rectangles, which determine in what region the logo resides for faster processing. */ - calculate_bounding_rectangle(&vf->priv->bounding_rectangle_posx1, &vf->priv->bounding_rectangle_posy1, - &vf->priv->bounding_rectangle_posx2, &vf->priv->bounding_rectangle_posy2, - vf->priv->filter); - calculate_bounding_rectangle(&vf->priv->bounding_rectangle_half_size_posx1, - &vf->priv->bounding_rectangle_half_size_posy1, - &vf->priv->bounding_rectangle_half_size_posx2, - &vf->priv->bounding_rectangle_half_size_posy2, - vf->priv->half_size_filter); - - vf->config=config; - vf->put_image=put_image; - vf->query_format=query_format; - return 1; -} - -/** - * \brief Meta data about our filter. - */ -const vf_info_t vf_info_remove_logo = { - "Removes a tv logo based on a mask image.", - "remove-logo", - "Robert Edele", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_rgbtest.c b/libmpcodecs/vf_rgbtest.c deleted file mode 100644 index 9179934175..0000000000 --- a/libmpcodecs/vf_rgbtest.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -//===========================================================================// - -struct vf_priv_s { - unsigned int fmt; - int w, h; -}; - -static unsigned int getfmt(unsigned int outfmt){ - switch(outfmt){ - case IMGFMT_RGB12: - case IMGFMT_RGB15: - case IMGFMT_RGB16: - case IMGFMT_RGB24: - case IMGFMT_RGBA: - case IMGFMT_ARGB: - case IMGFMT_BGR12: - case IMGFMT_BGR15: - case IMGFMT_BGR16: - case IMGFMT_BGR24: - case IMGFMT_BGRA: - case IMGFMT_ABGR: - return outfmt; - } - return 0; -} - -static void put_pixel(uint8_t *buf, int x, int y, int stride, int r, int g, int b, int fmt){ - switch(fmt){ - case IMGFMT_BGR12: ((uint16_t*)(buf + y*stride))[x]= - ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4); - break; - case IMGFMT_RGB12: ((uint16_t*)(buf + y*stride))[x]= - ((b >> 4) << 8) | ((g >> 4) << 4) | (r >> 4); - break; - case IMGFMT_BGR15: ((uint16_t*)(buf + y*stride))[x]= ((r>>3)<<10) | ((g>>3)<<5) | (b>>3); - break; - case IMGFMT_RGB15: ((uint16_t*)(buf + y*stride))[x]= ((b>>3)<<10) | ((g>>3)<<5) | (r>>3); - break; - case IMGFMT_BGR16: ((uint16_t*)(buf + y*stride))[x]= ((r>>3)<<11) | ((g>>2)<<5) | (b>>3); - break; - case IMGFMT_RGB16: ((uint16_t*)(buf + y*stride))[x]= ((b>>3)<<11) | ((g>>2)<<5) | (r>>3); - break; - case IMGFMT_RGB24: - buf[3*x + y*stride + 0]= r; - buf[3*x + y*stride + 1]= g; - buf[3*x + y*stride + 2]= b; - break; - case IMGFMT_BGR24: - buf[3*x + y*stride + 0]= b; - buf[3*x + y*stride + 1]= g; - buf[3*x + y*stride + 2]= r; - break; - case IMGFMT_RGBA: - buf[4*x + y*stride + 0]= r; - buf[4*x + y*stride + 1]= g; - buf[4*x + y*stride + 2]= b; - break; - case IMGFMT_BGRA: - buf[4*x + y*stride + 0]= b; - buf[4*x + y*stride + 1]= g; - buf[4*x + y*stride + 2]= r; - break; - case IMGFMT_ARGB: - buf[4*x + y*stride + 1]= r; - buf[4*x + y*stride + 2]= g; - buf[4*x + y*stride + 3]= b; - break; - case IMGFMT_ABGR: - buf[4*x + y*stride + 1]= b; - buf[4*x + y*stride + 2]= g; - buf[4*x + y*stride + 3]= r; - break; - } -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - if (vf->priv->w > 0) { d_width = width = vf->priv->w; } - if (vf->priv->h > 0) { d_height = height = vf->priv->h; } - vf->priv->fmt=getfmt(outfmt); - mp_msg(MSGT_VFILTER,MSGL_V,"rgb test format:%s\n", vo_format_name(outfmt)); - return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - int x, y; - int w = vf->priv->w > 0 ? vf->priv->w : mpi->w; - int h = vf->priv->h > 0 ? vf->priv->h : mpi->h; - - // hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,vf->priv->fmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - w, h); - - for(y=0; yplanes[0], x, y, dmpi->stride[0], r, g, b, vf->priv->fmt); - } - } - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int outfmt){ - unsigned int fmt=getfmt(outfmt); - if(!fmt) return 0; - return vf_next_query_format(vf,fmt) & (~VFCAP_CSP_SUPPORTED_BY_HW); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->query_format=query_format; - vf->priv=malloc(sizeof(struct vf_priv_s)); - vf->priv->w = vf->priv->h = 0; - if (args) - sscanf(args, "%d:%d", &vf->priv->w, &vf->priv->h); - return 1; -} - -const vf_info_t vf_info_rgbtest = { - "rgbtest", - "rgbtest", - "Michael Niedermayer", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_sab.c b/libmpcodecs/vf_sab.c deleted file mode 100644 index 649c3ccc43..0000000000 --- a/libmpcodecs/vf_sab.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2002 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include - -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "vf_scale.h" - - -//===========================================================================// - -typedef struct FilterParam{ - float radius; - float preFilterRadius; - float strength; - float quality; - struct SwsContext *preFilterContext; - uint8_t *preFilterBuf; - int preFilterStride; - int distWidth; - int distStride; - int *distCoeff; - int colorDiffCoeff[512]; -}FilterParam; - -struct vf_priv_s { - FilterParam luma; - FilterParam chroma; -}; - - -/***************************************************************************/ - -static int allocStuff(FilterParam *f, int width, int height){ - int stride= (width+7)&~7; - SwsVector *vec; - SwsFilter swsF; - int i,x,y; - f->preFilterBuf= av_malloc(stride*height); - f->preFilterStride= stride; - - vec = sws_getGaussianVec(f->preFilterRadius, f->quality); - swsF.lumH= swsF.lumV= vec; - swsF.chrH= swsF.chrV= NULL; - f->preFilterContext= sws_getContext( - width, height, PIX_FMT_GRAY8, width, height, PIX_FMT_GRAY8, SWS_POINT, &swsF, NULL, NULL); - - sws_freeVec(vec); - vec = sws_getGaussianVec(f->strength, 5.0); - for(i=0; i<512; i++){ - double d; - int index= i-256 + vec->length/2; - - if(index<0 || index>=vec->length) d= 0.0; - else d= vec->coeff[index]; - - f->colorDiffCoeff[i]= (int)(d/vec->coeff[vec->length/2]*(1<<12) + 0.5); - } - sws_freeVec(vec); - vec = sws_getGaussianVec(f->radius, f->quality); - f->distWidth= vec->length; - f->distStride= (vec->length+7)&~7; - f->distCoeff= av_malloc(f->distWidth*f->distStride*sizeof(int32_t)); - - for(y=0; ylength; y++){ - for(x=0; xlength; x++){ - double d= vec->coeff[x] * vec->coeff[y]; - - f->distCoeff[x + y*f->distStride]= (int)(d*(1<<10) + 0.5); -// if(y==vec->length/2) -// printf("%6d ", f->distCoeff[x + y*f->distStride]); - } - } - sws_freeVec(vec); - - return 0; -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - int sw, sh; -//__asm__ volatile("emms\n\t"); - allocStuff(&vf->priv->luma, width, height); - - mp_get_chroma_shift(outfmt, &sw, &sh, NULL); - allocStuff(&vf->priv->chroma, width>>sw, height>>sh); - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void freeBuffers(FilterParam *f){ - if(f->preFilterContext) sws_freeContext(f->preFilterContext); - f->preFilterContext=NULL; - - av_free(f->preFilterBuf); - f->preFilterBuf=NULL; - - av_free(f->distCoeff); - f->distCoeff=NULL; -} - -static void uninit(struct vf_instance *vf){ - if(!vf->priv) return; - - freeBuffers(&vf->priv->luma); - freeBuffers(&vf->priv->chroma); - - free(vf->priv); - vf->priv=NULL; -} - -static inline void blur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, FilterParam *fp){ - int x, y; - FilterParam f= *fp; - const int radius= f.distWidth/2; - const uint8_t* const srcArray[MP_MAX_PLANES] = {src}; - uint8_t *dstArray[MP_MAX_PLANES]= {f.preFilterBuf}; - int srcStrideArray[MP_MAX_PLANES]= {srcStride}; - int dstStrideArray[MP_MAX_PLANES]= {f.preFilterStride}; - -// f.preFilterContext->swScale(f.preFilterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray); - sws_scale(f.preFilterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray); - - for(y=0; y= radius && x < w - radius){ - for(dy=0; dy=h) iy= h+h-iy-1; - - for(dx=0; dx=h) iy= h+h-iy-1; - - for(dx=0; dx=w) ix= w+w-ix-1; - - factor= f.colorDiffCoeff[256+preVal - f.preFilterBuf[ix + iy*f.preFilterStride] ] - *f.distCoeff[dx + dy*f.distStride]; - sum+= src[ix + iy*srcStride] *factor; - div+= factor; - } - } - } - dst[x + y*dstStride]= (sum + div/2)/div; - } - } -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - int cw= mpi->w >> mpi->chroma_x_shift; - int ch= mpi->h >> mpi->chroma_y_shift; - - mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w,mpi->h); - - assert(mpi->flags&MP_IMGFLAG_PLANAR); - - blur(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], &vf->priv->luma); - blur(dmpi->planes[1], mpi->planes[1], cw , ch , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma); - blur(dmpi->planes[2], mpi->planes[2], cw , ch , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma); - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt) - { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_YVU9: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int vf_open(vf_instance_t *vf, char *args){ - int e; - - vf->config=config; - vf->put_image=put_image; -// vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - if(args==NULL) return 0; - - e=sscanf(args, "%f:%f:%f:%f:%f:%f", - &vf->priv->luma.radius, - &vf->priv->luma.preFilterRadius, - &vf->priv->luma.strength, - &vf->priv->chroma.radius, - &vf->priv->chroma.preFilterRadius, - &vf->priv->chroma.strength - ); - - vf->priv->luma.quality = vf->priv->chroma.quality= 3.0; - - if(e==3){ - vf->priv->chroma.radius= vf->priv->luma.radius; - vf->priv->chroma.preFilterRadius = vf->priv->luma.preFilterRadius; - vf->priv->chroma.strength= vf->priv->luma.strength; - }else if(e!=6) - return 0; - -// if(vf->priv->luma.radius < 0) return 0; -// if(vf->priv->chroma.radius < 0) return 0; - - return 1; -} - -const vf_info_t vf_info_sab = { - "shape adaptive blur", - "sab", - "Michael Niedermayer", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_smartblur.c b/libmpcodecs/vf_smartblur.c deleted file mode 100644 index da6f3547bf..0000000000 --- a/libmpcodecs/vf_smartblur.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2002 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include -#include - -#include "mp_msg.h" -#include "libavutil/avutil.h" -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libswscale/swscale.h" -#include "vf_scale.h" - -//===========================================================================// - -typedef struct FilterParam{ - float radius; - float strength; - int threshold; - float quality; - struct SwsContext *filterContext; -}FilterParam; - -struct vf_priv_s { - FilterParam luma; - FilterParam chroma; -}; - - -/***************************************************************************/ - -static int allocStuff(FilterParam *f, int width, int height){ - SwsVector *vec; - SwsFilter swsF; - - vec = sws_getGaussianVec(f->radius, f->quality); - sws_scaleVec(vec, f->strength); - vec->coeff[vec->length/2]+= 1.0 - f->strength; - swsF.lumH= swsF.lumV= vec; - swsF.chrH= swsF.chrV= NULL; - f->filterContext= sws_getContext( - width, height, PIX_FMT_GRAY8, width, height, PIX_FMT_GRAY8, SWS_BICUBIC, &swsF, NULL, NULL); - - sws_freeVec(vec); - - return 0; -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - int sw, sh; - - allocStuff(&vf->priv->luma, width, height); - - mp_get_chroma_shift(outfmt, &sw, &sh, NULL); - allocStuff(&vf->priv->chroma, width>>sw, height>>sh); - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void freeBuffers(FilterParam *f){ - if(f->filterContext) sws_freeContext(f->filterContext); - f->filterContext=NULL; -} - -static void uninit(struct vf_instance *vf){ - if(!vf->priv) return; - - freeBuffers(&vf->priv->luma); - freeBuffers(&vf->priv->chroma); - - free(vf->priv); - vf->priv=NULL; -} - -static inline void blur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, FilterParam *fp){ - int x, y; - FilterParam f= *fp; - const uint8_t* const srcArray[MP_MAX_PLANES] = {src}; - uint8_t *dstArray[MP_MAX_PLANES]= {dst}; - int srcStrideArray[MP_MAX_PLANES]= {srcStride}; - int dstStrideArray[MP_MAX_PLANES]= {dstStride}; - - sws_scale(f.filterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray); - - if(f.threshold > 0){ - for(y=0; y 0){ - if(diff > 2*f.threshold){ - dst[x + y*dstStride]= orig; - }else if(diff > f.threshold){ - dst[x + y*dstStride]= filtered + diff - f.threshold; - } - }else{ - if(-diff > 2*f.threshold){ - dst[x + y*dstStride]= orig; - }else if(-diff > f.threshold){ - dst[x + y*dstStride]= filtered + diff + f.threshold; - } - } - } - } - }else if(f.threshold < 0){ - for(y=0; y 0){ - if(diff > -2*f.threshold){ - }else if(diff > -f.threshold){ - dst[x + y*dstStride]= orig - diff - f.threshold; - }else - dst[x + y*dstStride]= orig; - }else{ - if(diff < 2*f.threshold){ - }else if(diff < f.threshold){ - dst[x + y*dstStride]= orig - diff + f.threshold; - }else - dst[x + y*dstStride]= orig; - } - } - } - } -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - int cw= mpi->w >> mpi->chroma_x_shift; - int ch= mpi->h >> mpi->chroma_y_shift; - bool threshold = vf->priv->luma.threshold || vf->priv->chroma.threshold; - - mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE| - (threshold ? MP_IMGFLAG_READABLE : 0), - mpi->w,mpi->h); - - assert(mpi->flags&MP_IMGFLAG_PLANAR); - - blur(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], &vf->priv->luma); - blur(dmpi->planes[1], mpi->planes[1], cw , ch , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma); - blur(dmpi->planes[2], mpi->planes[2], cw , ch , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma); - - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt) - { - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_YVU9: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int vf_open(vf_instance_t *vf, char *args){ - int e; - - vf->config=config; - vf->put_image=put_image; -// vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - if(args==NULL) return 0; - - e=sscanf(args, "%f:%f:%d:%f:%f:%d", - &vf->priv->luma.radius, - &vf->priv->luma.strength, - &vf->priv->luma.threshold, - &vf->priv->chroma.radius, - &vf->priv->chroma.strength, - &vf->priv->chroma.threshold - ); - - vf->priv->luma.quality = vf->priv->chroma.quality= 3.0; - - if(e==3){ - vf->priv->chroma.radius= vf->priv->luma.radius; - vf->priv->chroma.strength= vf->priv->luma.strength; - vf->priv->chroma.threshold = vf->priv->luma.threshold; - }else if(e!=6) - return 0; - - return 1; -} - -const vf_info_t vf_info_smartblur = { - "smart blur", - "smartblur", - "Michael Niedermayer", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_softskip.c b/libmpcodecs/vf_softskip.c deleted file mode 100644 index fe572cb0b0..0000000000 --- a/libmpcodecs/vf_softskip.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - int skipflag; -}; - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - - if (vf->priv->skipflag) - return vf->priv->skipflag = 0; - - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_EXPORT, 0, mpi->width, mpi->height); - vf_clone_mpi_attributes(dmpi, mpi); - - dmpi->planes[0] = mpi->planes[0]; - dmpi->stride[0] = mpi->stride[0]; - if (dmpi->flags&MP_IMGFLAG_PLANAR) { - dmpi->planes[1] = mpi->planes[1]; - dmpi->stride[1] = mpi->stride[1]; - dmpi->planes[2] = mpi->planes[2]; - dmpi->stride[2] = mpi->stride[2]; - } - - return vf_next_put_image(vf, dmpi, pts); -} - -static int control(struct vf_instance *vf, int request, void* data) -{ - switch (request) { - case VFCTRL_SKIP_NEXT_FRAME: - vf->priv->skipflag = 1; - return CONTROL_TRUE; - } - return vf_next_control(vf, request, data); -} - -#if 0 -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - /* FIXME - figure out which other formats work */ - switch (fmt) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - return vf_next_query_format(vf, fmt); - } - return 0; -} -#endif - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - vf->put_image = put_image; - vf->control = control; - vf->uninit = uninit; - vf->priv = calloc(1, sizeof(struct vf_priv_s)); - return 1; -} - -const vf_info_t vf_info_softskip = { - "soft (post-filter) frame skipping for encoding", - "softskip", - "Rich Felker", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_spp.c b/libmpcodecs/vf_spp.c deleted file mode 100644 index e0c1e64449..0000000000 --- a/libmpcodecs/vf_spp.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * Copyright (C) 2003 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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. - */ - -/* - * This implementation is based on an algorithm described in - * "Aria Nosratinia Embedded Post-Processing for - * Enhancement of Compressed Images (1999)" - * (http://citeseer.nj.nec.com/nosratinia99embedded.html) - */ - - -#include -#include -#include -#include -#include - -#include "config.h" - -#include "mp_msg.h" -#include "cpudetect.h" - -#include "libavutil/intreadwrite.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libvo/fastmemcpy.h" - -#define XMIN(a,b) ((a) < (b) ? (a) : (b)) - -//===========================================================================// -static const uint8_t __attribute__((aligned(8))) dither[8][8]={ -{ 0, 48, 12, 60, 3, 51, 15, 63, }, -{ 32, 16, 44, 28, 35, 19, 47, 31, }, -{ 8, 56, 4, 52, 11, 59, 7, 55, }, -{ 40, 24, 36, 20, 43, 27, 39, 23, }, -{ 2, 50, 14, 62, 1, 49, 13, 61, }, -{ 34, 18, 46, 30, 33, 17, 45, 29, }, -{ 10, 58, 6, 54, 9, 57, 5, 53, }, -{ 42, 26, 38, 22, 41, 25, 37, 21, }, -}; - -static const uint8_t offset[127][2]= { -{0,0}, -{0,0}, {4,4}, -{0,0}, {2,2}, {6,4}, {4,6}, -{0,0}, {5,1}, {2,2}, {7,3}, {4,4}, {1,5}, {6,6}, {3,7}, - -{0,0}, {4,0}, {1,1}, {5,1}, {3,2}, {7,2}, {2,3}, {6,3}, -{0,4}, {4,4}, {1,5}, {5,5}, {3,6}, {7,6}, {2,7}, {6,7}, - -{0,0}, {0,2}, {0,4}, {0,6}, {1,1}, {1,3}, {1,5}, {1,7}, -{2,0}, {2,2}, {2,4}, {2,6}, {3,1}, {3,3}, {3,5}, {3,7}, -{4,0}, {4,2}, {4,4}, {4,6}, {5,1}, {5,3}, {5,5}, {5,7}, -{6,0}, {6,2}, {6,4}, {6,6}, {7,1}, {7,3}, {7,5}, {7,7}, - -{0,0}, {4,4}, {0,4}, {4,0}, {2,2}, {6,6}, {2,6}, {6,2}, -{0,2}, {4,6}, {0,6}, {4,2}, {2,0}, {6,4}, {2,4}, {6,0}, -{1,1}, {5,5}, {1,5}, {5,1}, {3,3}, {7,7}, {3,7}, {7,3}, -{1,3}, {5,7}, {1,7}, {5,3}, {3,1}, {7,5}, {3,5}, {7,1}, -{0,1}, {4,5}, {0,5}, {4,1}, {2,3}, {6,7}, {2,7}, {6,3}, -{0,3}, {4,7}, {0,7}, {4,3}, {2,1}, {6,5}, {2,5}, {6,1}, -{1,0}, {5,4}, {1,4}, {5,0}, {3,2}, {7,6}, {3,6}, {7,2}, -{1,2}, {5,6}, {1,6}, {5,2}, {3,0}, {7,4}, {3,4}, {7,0}, -}; - -struct vf_priv_s { - int log2_count; - int qp; - int mode; - int mpeg2; - int temp_stride; - uint8_t *src; - int16_t *temp; - AVCodecContext *avctx; - DSPContext dsp; - char *non_b_qp; -}; - -#define SHIFT 22 - -static void hardthresh_c(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){ - int i; - int bias= 0; //FIXME - unsigned int threshold1, threshold2; - - threshold1= qp*((1<<4) - bias) - 1; - threshold2= (threshold1<<1); - - memset(dst, 0, 64*sizeof(DCTELEM)); - dst[0]= (src[0] + 4)>>3; - - for(i=1; i<64; i++){ - int level= src[i]; - if(((unsigned)(level+threshold1))>threshold2){ - const int j= permutation[i]; - dst[j]= (level + 4)>>3; - } - } -} - -static void softthresh_c(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){ - int i; - int bias= 0; //FIXME - unsigned int threshold1, threshold2; - - threshold1= qp*((1<<4) - bias) - 1; - threshold2= (threshold1<<1); - - memset(dst, 0, 64*sizeof(DCTELEM)); - dst[0]= (src[0] + 4)>>3; - - for(i=1; i<64; i++){ - int level= src[i]; - if(((unsigned)(level+threshold1))>threshold2){ - const int j= permutation[i]; - if(level>0) - dst[j]= (level - threshold1 + 4)>>3; - else - dst[j]= (level + threshold1 + 4)>>3; - } - } -} - -#if HAVE_MMX -static void hardthresh_mmx(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){ - int bias= 0; //FIXME - unsigned int threshold1; - - threshold1= qp*((1<<4) - bias) - 1; - - __asm__ volatile( -#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \ - "movq " #src0 ", %%mm0 \n\t"\ - "movq " #src1 ", %%mm1 \n\t"\ - "movq " #src2 ", %%mm2 \n\t"\ - "movq " #src3 ", %%mm3 \n\t"\ - "psubw %%mm4, %%mm0 \n\t"\ - "psubw %%mm4, %%mm1 \n\t"\ - "psubw %%mm4, %%mm2 \n\t"\ - "psubw %%mm4, %%mm3 \n\t"\ - "paddusw %%mm5, %%mm0 \n\t"\ - "paddusw %%mm5, %%mm1 \n\t"\ - "paddusw %%mm5, %%mm2 \n\t"\ - "paddusw %%mm5, %%mm3 \n\t"\ - "paddw %%mm6, %%mm0 \n\t"\ - "paddw %%mm6, %%mm1 \n\t"\ - "paddw %%mm6, %%mm2 \n\t"\ - "paddw %%mm6, %%mm3 \n\t"\ - "psubusw %%mm6, %%mm0 \n\t"\ - "psubusw %%mm6, %%mm1 \n\t"\ - "psubusw %%mm6, %%mm2 \n\t"\ - "psubusw %%mm6, %%mm3 \n\t"\ - "psraw $3, %%mm0 \n\t"\ - "psraw $3, %%mm1 \n\t"\ - "psraw $3, %%mm2 \n\t"\ - "psraw $3, %%mm3 \n\t"\ -\ - "movq %%mm0, %%mm7 \n\t"\ - "punpcklwd %%mm2, %%mm0 \n\t" /*A*/\ - "punpckhwd %%mm2, %%mm7 \n\t" /*C*/\ - "movq %%mm1, %%mm2 \n\t"\ - "punpcklwd %%mm3, %%mm1 \n\t" /*B*/\ - "punpckhwd %%mm3, %%mm2 \n\t" /*D*/\ - "movq %%mm0, %%mm3 \n\t"\ - "punpcklwd %%mm1, %%mm0 \n\t" /*A*/\ - "punpckhwd %%mm7, %%mm3 \n\t" /*C*/\ - "punpcklwd %%mm2, %%mm7 \n\t" /*B*/\ - "punpckhwd %%mm2, %%mm1 \n\t" /*D*/\ -\ - "movq %%mm0, " #dst0 " \n\t"\ - "movq %%mm7, " #dst1 " \n\t"\ - "movq %%mm3, " #dst2 " \n\t"\ - "movq %%mm1, " #dst3 " \n\t" - - "movd %2, %%mm4 \n\t" - "movd %3, %%mm5 \n\t" - "movd %4, %%mm6 \n\t" - "packssdw %%mm4, %%mm4 \n\t" - "packssdw %%mm5, %%mm5 \n\t" - "packssdw %%mm6, %%mm6 \n\t" - "packssdw %%mm4, %%mm4 \n\t" - "packssdw %%mm5, %%mm5 \n\t" - "packssdw %%mm6, %%mm6 \n\t" - REQUANT_CORE( (%1), 8(%1), 16(%1), 24(%1), (%0), 8(%0), 64(%0), 72(%0)) - REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0)) - REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0)) - REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0)) - : : "r" (src), "r" (dst), "g" (threshold1+1), "g" (threshold1+5), "g" (threshold1-4) //FIXME maybe more accurate then needed? - ); - dst[0]= (src[0] + 4)>>3; -} - -static void softthresh_mmx(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){ - int bias= 0; //FIXME - unsigned int threshold1; - - threshold1= qp*((1<<4) - bias) - 1; - - __asm__ volatile( -#undef REQUANT_CORE -#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \ - "movq " #src0 ", %%mm0 \n\t"\ - "movq " #src1 ", %%mm1 \n\t"\ - "pxor %%mm6, %%mm6 \n\t"\ - "pxor %%mm7, %%mm7 \n\t"\ - "pcmpgtw %%mm0, %%mm6 \n\t"\ - "pcmpgtw %%mm1, %%mm7 \n\t"\ - "pxor %%mm6, %%mm0 \n\t"\ - "pxor %%mm7, %%mm1 \n\t"\ - "psubusw %%mm4, %%mm0 \n\t"\ - "psubusw %%mm4, %%mm1 \n\t"\ - "pxor %%mm6, %%mm0 \n\t"\ - "pxor %%mm7, %%mm1 \n\t"\ - "movq " #src2 ", %%mm2 \n\t"\ - "movq " #src3 ", %%mm3 \n\t"\ - "pxor %%mm6, %%mm6 \n\t"\ - "pxor %%mm7, %%mm7 \n\t"\ - "pcmpgtw %%mm2, %%mm6 \n\t"\ - "pcmpgtw %%mm3, %%mm7 \n\t"\ - "pxor %%mm6, %%mm2 \n\t"\ - "pxor %%mm7, %%mm3 \n\t"\ - "psubusw %%mm4, %%mm2 \n\t"\ - "psubusw %%mm4, %%mm3 \n\t"\ - "pxor %%mm6, %%mm2 \n\t"\ - "pxor %%mm7, %%mm3 \n\t"\ -\ - "paddsw %%mm5, %%mm0 \n\t"\ - "paddsw %%mm5, %%mm1 \n\t"\ - "paddsw %%mm5, %%mm2 \n\t"\ - "paddsw %%mm5, %%mm3 \n\t"\ - "psraw $3, %%mm0 \n\t"\ - "psraw $3, %%mm1 \n\t"\ - "psraw $3, %%mm2 \n\t"\ - "psraw $3, %%mm3 \n\t"\ -\ - "movq %%mm0, %%mm7 \n\t"\ - "punpcklwd %%mm2, %%mm0 \n\t" /*A*/\ - "punpckhwd %%mm2, %%mm7 \n\t" /*C*/\ - "movq %%mm1, %%mm2 \n\t"\ - "punpcklwd %%mm3, %%mm1 \n\t" /*B*/\ - "punpckhwd %%mm3, %%mm2 \n\t" /*D*/\ - "movq %%mm0, %%mm3 \n\t"\ - "punpcklwd %%mm1, %%mm0 \n\t" /*A*/\ - "punpckhwd %%mm7, %%mm3 \n\t" /*C*/\ - "punpcklwd %%mm2, %%mm7 \n\t" /*B*/\ - "punpckhwd %%mm2, %%mm1 \n\t" /*D*/\ -\ - "movq %%mm0, " #dst0 " \n\t"\ - "movq %%mm7, " #dst1 " \n\t"\ - "movq %%mm3, " #dst2 " \n\t"\ - "movq %%mm1, " #dst3 " \n\t" - - "movd %2, %%mm4 \n\t" - "movd %3, %%mm5 \n\t" - "packssdw %%mm4, %%mm4 \n\t" - "packssdw %%mm5, %%mm5 \n\t" - "packssdw %%mm4, %%mm4 \n\t" - "packssdw %%mm5, %%mm5 \n\t" - REQUANT_CORE( (%1), 8(%1), 16(%1), 24(%1), (%0), 8(%0), 64(%0), 72(%0)) - REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0)) - REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0)) - REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0)) - : : "r" (src), "r" (dst), "g" (threshold1), "rm" (4) //FIXME maybe more accurate then needed? - ); - - dst[0]= (src[0] + 4)>>3; -} -#endif - -static inline void add_block(int16_t *dst, int stride, DCTELEM block[64]){ - int y; - - for(y=0; y<8; y++){ - *(uint32_t*)&dst[0 + y*stride]+= *(uint32_t*)&block[0 + y*8]; - *(uint32_t*)&dst[2 + y*stride]+= *(uint32_t*)&block[2 + y*8]; - *(uint32_t*)&dst[4 + y*stride]+= *(uint32_t*)&block[4 + y*8]; - *(uint32_t*)&dst[6 + y*stride]+= *(uint32_t*)&block[6 + y*8]; - } -} - -static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){ - int y, x; - -#define STORE(pos) \ - temp= ((src[x + y*src_stride + pos]<>6;\ - if(temp & 0x100) temp= ~(temp>>31);\ - dst[x + y*dst_stride + pos]= temp; - - for(y=0; ylog2_count; - const int stride= is_luma ? p->temp_stride : ((width+16+15)&(~15)); - uint64_t __attribute__((aligned(16))) block_align[32]; - DCTELEM *block = (DCTELEM *)block_align; - DCTELEM *block2= (DCTELEM *)(block_align+16); - - if (!src || !dst) return; // HACK avoid crash for Y8 colourspace - for(y=0; ysrc + index, src + y*src_stride, width); - for(x=0; x<8; x++){ - p->src[index - x - 1]= p->src[index + x ]; - p->src[index + width + x ]= p->src[index + width - x - 1]; - } - } - for(y=0; y<8; y++){ - fast_memcpy(p->src + ( 7-y)*stride, p->src + ( y+8)*stride, stride); - fast_memcpy(p->src + (height+8+y)*stride, p->src + (height-y+7)*stride, stride); - } - //FIXME (try edge emu) - - for(y=0; ytemp + (8+y)*stride, 0, 8*stride*sizeof(int16_t)); - for(x=0; xqp) - qp= p->qp; - else{ - qp= qp_store[ (XMIN(x, width-1)>>qps) + (XMIN(y, height-1)>>qps) * qp_stride]; - qp = FFMAX(1, norm_qscale(qp, p->mpeg2)); - } - for(i=0; idsp.get_pixels(block, p->src + index, stride); - p->dsp.fdct(block); - requantize(block2, block, qp, p->dsp.idct_permutation); - p->dsp.idct(block2); - add_block(p->temp + index, stride, block2); - } - } - if(y) - store_slice(dst + (y-8)*dst_stride, p->temp + 8 + y*stride, dst_stride, stride, width, XMIN(8, height+8-y), 6-p->log2_count); - } -#if 0 - for(y=0; y>6) ^ (y>>6)) & 1) == 0) - dst[x + y*dst_stride]= p->src[8 + 8*stride + x + y*stride]; - if((x&63) == 0 || (y&63)==0) - dst[x + y*dst_stride] += 128; - } - } -#endif - //FIXME reorder for better caching -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - int h= (height+16+15)&(~15); - - vf->priv->temp_stride= (width+16+15)&(~15); - vf->priv->temp= malloc(vf->priv->temp_stride*h*sizeof(int16_t)); - vf->priv->src = malloc(vf->priv->temp_stride*h*sizeof(uint8_t)); - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi){ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // no DR, so get a new image! hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->width,mpi->height); - vf_clone_mpi_attributes(dmpi, mpi); - }else{ - dmpi=vf->dmpi; - } - - vf->priv->mpeg2= mpi->qscale_type; - if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){ - int w = mpi->qstride; - int h = (mpi->h + 15) >> 4; - if (!w) { - w = (mpi->w + 15) >> 4; - h = 1; - } - if(!vf->priv->non_b_qp) - vf->priv->non_b_qp= malloc(w*h); - fast_memcpy(vf->priv->non_b_qp, mpi->qscale, w*h); - } - if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){ - char *qp_tab= vf->priv->non_b_qp; - if((vf->priv->mode&4) || !qp_tab) - qp_tab= mpi->qscale; - - if(qp_tab || vf->priv->qp){ - filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, qp_tab, mpi->qstride, 1); - filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0); - filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0); - }else{ - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]); - memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]); - } - } - -#if HAVE_MMX - if(gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t"); -#endif -#if HAVE_MMX2 - if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t"); -#endif - - return vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf){ - if(!vf->priv) return; - - free(vf->priv->temp); - vf->priv->temp= NULL; - free(vf->priv->src); - vf->priv->src= NULL; - free(vf->priv->avctx); - vf->priv->avctx= NULL; - free(vf->priv->non_b_qp); - vf->priv->non_b_qp= NULL; - - free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return vf_next_query_format(vf,fmt); - } - return 0; -} - -static int control(struct vf_instance *vf, int request, void* data){ - switch(request){ - case VFCTRL_QUERY_MAX_PP_LEVEL: - return 6; - case VFCTRL_SET_PP_LEVEL: - vf->priv->log2_count= *((unsigned int*)data); - return CONTROL_TRUE; - } - return vf_next_control(vf,request,data); -} - -static int vf_open(vf_instance_t *vf, char *args){ - - int log2c=-1; - - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->control= control; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - vf->priv->avctx= avcodec_alloc_context(); - ff_dsputil_init(&vf->priv->dsp, vf->priv->avctx); - - vf->priv->log2_count= 3; - - if (args) sscanf(args, "%d:%d:%d", &log2c, &vf->priv->qp, &vf->priv->mode); - - if( log2c >=0 && log2c <=6 ) - vf->priv->log2_count = log2c; - - if(vf->priv->qp < 0) - vf->priv->qp = 0; - - switch(vf->priv->mode&3){ - default: - case 0: requantize= hardthresh_c; break; - case 1: requantize= softthresh_c; break; - } - -#if HAVE_MMX - if(gCpuCaps.hasMMX){ - store_slice= store_slice_mmx; - switch(vf->priv->mode&3){ - case 0: requantize= hardthresh_mmx; break; - case 1: requantize= softthresh_mmx; break; - } - } -#endif - - return 1; -} - -const vf_info_t vf_info_spp = { - "simple postprocess", - "spp", - "Michael Niedermayer", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_telecine.c b/libmpcodecs/vf_telecine.c deleted file mode 100644 index 4ae96f2434..0000000000 --- a/libmpcodecs/vf_telecine.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/fastmemcpy.h" - -struct vf_priv_s { - int frame; - double pts; - double lastpts; - mp_image_t *buffered_mpi; -}; - -static int continue_buffered_image_fullframe(struct vf_instance *vf) -{ - mp_image_t *mpi = vf->priv->buffered_mpi; - mp_image_t *dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE, mpi->width, mpi->height); - - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, - dmpi->stride[0], mpi->stride[0]); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[2], mpi->stride[2]); - } - return vf_next_put_image(vf, dmpi, vf->priv->pts); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - int ret; - - vf->priv->frame = (vf->priv->frame+1)%4; - - if (pts != MP_NOPTS_VALUE) { - if (vf->priv->lastpts == MP_NOPTS_VALUE) { - vf->priv->pts = pts; - vf->priv->lastpts = pts; - } else { - // we only increase by 80% of input pts at each frame; in the case - // in which we render two frames, we jump back - // this turns 23.98fps perfectly into 29.97fps - vf->priv->pts += 0.8 * (pts - vf->priv->lastpts); - vf->priv->lastpts = pts; - } - } - - ret = 0; - // 0/0 1/1 2/2 2/3 3/0 - switch (vf->priv->frame) { - case 0: - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE, mpi->width, mpi->height); - my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0], - mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1], - mpi->planes[1]+mpi->stride[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2], - mpi->planes[2]+mpi->stride[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - ret = vf_next_put_image(vf, dmpi, vf->priv->pts); - vf->priv->pts = pts; - vf->priv->buffered_mpi = mpi; - vf_queue_frame(vf, continue_buffered_image_fullframe); - return ret; - case 1: - case 2: - vf->priv->buffered_mpi = mpi; - return continue_buffered_image_fullframe(vf); - case 3: - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE, mpi->width, mpi->height); - my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0], - mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1], - mpi->planes[1]+mpi->stride[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2], - mpi->planes[2]+mpi->stride[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - ret = vf_next_put_image(vf, dmpi, vf->priv->pts); - my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - return ret; - } - return 0; -} - -#if 0 -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - /* FIXME - figure out which other formats work */ - switch (fmt) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} -#endif - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - //vf->config = config; - vf->put_image = put_image; - //vf->query_format = query_format; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - vf->priv = calloc(1, sizeof(struct vf_priv_s)); - vf->priv->frame = 1; - if (args) sscanf(args, "%d", &vf->priv->frame); - vf->priv->frame--; - vf->priv->pts = MP_NOPTS_VALUE; - vf->priv->lastpts = MP_NOPTS_VALUE; - return 1; -} - -const vf_info_t vf_info_telecine = { - "telecine filter", - "telecine", - "Rich Felker", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_test.c b/libmpcodecs/vf_test.c deleted file mode 100644 index aeb2763200..0000000000 --- a/libmpcodecs/vf_test.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2002 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -//===========================================================================// - -#include -#include - -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define ABS(a,b) ((a) > 0 ? (a) : -(a)) - -#define WIDTH 512 -#define HEIGHT 512 - -struct vf_priv_s { - int frame_num; -}; - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - if(vf_next_query_format(vf,IMGFMT_YV12)<=0){ - mp_tmsg(MSGT_VFILTER, MSGL_WARN, "%s not supported by next filter/vo :(\n", "YV12"); - return 0; - } - - //hmm whats the meaning of these ... ;) - d_width= width= WIDTH; - d_height= height= HEIGHT; - - return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_YV12); -} - -static double c[64]; - -static void initIdct(void) -{ - int i; - - for (i=0; i<8; i++) - { - double s= i==0 ? sqrt(0.125) : 0.5; - int j; - - for(j=0; j<8; j++) - c[i*8+j]= s*cos((3.141592654/8.0)*i*(j+0.5)); - } -} - - -static void idct(uint8_t *dst, int dstStride, int src[64]) -{ - int i, j, k; - double tmp[64]; - - for(i=0; i<8; i++) - { - for(j=0; j<8; j++) - { - double sum= 0.0; - - for(k=0; k<8; k++) - sum+= c[k*8+j]*src[8*i+k]; - - tmp[8*i+j]= sum; - } - } - - for(j=0; j<8; j++) - { - for(i=0; i<8; i++) - { - int v; - double sum= 0.0; - - for(k=0; k<8; k++) - sum+= c[k*8+i]*tmp[8*k+j]; - - v= (int)floor(sum+0.5); - if(v<0) v=0; - else if(v>255) v=255; - - dst[dstStride*i + j] = v; - } - } -} - -static void drawDc(uint8_t *dst, int stride, int color, int w, int h) -{ - int y; - for(y=0; ypriv->frame_num; - - // hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,IMGFMT_YV12, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - WIDTH, HEIGHT); - - // clean - memset(dmpi->planes[0], 0, dmpi->stride[0]*dmpi->h); - memset(dmpi->planes[1], 128, dmpi->stride[1]*dmpi->h>>dmpi->chroma_y_shift); - memset(dmpi->planes[2], 128, dmpi->stride[2]*dmpi->h>>dmpi->chroma_y_shift); - - if(frame%30) - { - switch(frame/30) - { - case 0: dc1Test(dmpi->planes[0], dmpi->stride[0], 256, 256, frame%30); break; - case 1: dc1Test(dmpi->planes[1], dmpi->stride[1], 256, 256, frame%30); break; - case 2: freq1Test(dmpi->planes[0], dmpi->stride[0], frame%30); break; - case 3: freq1Test(dmpi->planes[1], dmpi->stride[1], frame%30); break; - case 4: amp1Test(dmpi->planes[0], dmpi->stride[0], frame%30); break; - case 5: amp1Test(dmpi->planes[1], dmpi->stride[1], frame%30); break; - case 6: cbp1Test(dmpi->planes , dmpi->stride , frame%30); break; - case 7: mv1Test(dmpi->planes[0], dmpi->stride[0], frame%30); break; - case 8: ring1Test(dmpi->planes[0], dmpi->stride[0], frame%30); break; - case 9: ring2Test(dmpi->planes[0], dmpi->stride[0], frame%30); break; - } - } - - frame++; - vf->priv->frame_num= frame; - return vf_next_put_image(vf,dmpi, pts); -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - return vf_next_query_format(vf,IMGFMT_YV12) & (~VFCAP_CSP_SUPPORTED_BY_HW); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->query_format=query_format; - vf->priv=malloc(sizeof(struct vf_priv_s)); - vf->priv->frame_num= args ? atoi(args) : 0; - initIdct(); - return 1; -} - -const vf_info_t vf_info_test = { - "test pattern generator", - "test", - "Michael Niedermayer", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_tfields.c b/libmpcodecs/vf_tfields.c deleted file mode 100644 index b4fa7a46bf..0000000000 --- a/libmpcodecs/vf_tfields.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "options.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/fastmemcpy.h" - -struct vf_priv_s { - int mode; - int parity; - int buffered_i; - mp_image_t *buffered_mpi; - double buffered_pts; -}; - -static void deint(unsigned char *dest, int ds, unsigned char *src, int ss, int w, int h, int field) -{ - int x, y; - src += ss; - dest += ds; - h--; - if (field) { - fast_memcpy(dest - ds, src - ss, w); - src += ss; - dest += ds; - h--; - } - for (y=h/2; y > 0; y--) { - dest[0] = src[0]; - for (x=1; x src[x]) && (src[x+ss] > src[x]))) { - //dest[x] = (src[x+ss] + src[x-ss])>>1; - dest[x] = ((src[x+ss]<<1) + (src[x-ss]<<1) - + src[x+ss+1] + src[x-ss+1] - + src[x+ss-1] + src[x-ss-1])>>3; - } - else dest[x] = src[x]; - } - dest[w-1] = src[w-1]; - dest += ds<<1; - src += ss<<1; - } - if (h & 1) - fast_memcpy(dest, src, w); -} - -#if HAVE_MMX2 -static void qpel_li_MMX2(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up) -{ - int i, j, ssd=ss; - long crap1, crap2; - if (up) { - ssd = -ss; - fast_memcpy(d, s, w); - d += ds; - s += ss; - } - for (i=h-1; i; i--) { - __asm__ volatile( - "pxor %%mm7, %%mm7 \n\t" - "2: \n\t" - "movq (%%"REG_S"), %%mm0 \n\t" - "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t" - "pavgb %%mm0, %%mm1 \n\t" - "add $8, %%"REG_S" \n\t" - "pavgb %%mm0, %%mm1 \n\t" - "movq %%mm1, (%%"REG_D") \n\t" - "add $8, %%"REG_D" \n\t" - "decl %%ecx \n\t" - "jnz 2b \n\t" - : "=S"(crap1), "=D"(crap2) - : "c"(w>>3), "S"(s), "D"(d), "a"((long)ssd) - ); - for (j=w-(w&7); j>2; - d += ds; - s += ss; - } - if (!up) fast_memcpy(d, s, w); - __asm__ volatile("emms \n\t" : : : "memory"); -} -#endif - -#if HAVE_MMX -static void qpel_li_MMX(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up) -{ - int i, j, ssd=ss; - int crap1, crap2; - if (up) { - ssd = -ss; - fast_memcpy(d, s, w); - d += ds; - s += ss; - } - for (i=h-1; i; i--) { - __asm__ volatile( - "pxor %%mm7, %%mm7 \n\t" - "3: \n\t" - "movq (%%"REG_S"), %%mm0 \n\t" - "movq (%%"REG_S"), %%mm1 \n\t" - "movq (%%"REG_S",%%"REG_a"), %%mm2 \n\t" - "movq (%%"REG_S",%%"REG_a"), %%mm3 \n\t" - "add $8, %%"REG_S" \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddw %%mm0, %%mm2 \n\t" - "paddw %%mm1, %%mm3 \n\t" - "paddw %%mm0, %%mm2 \n\t" - "paddw %%mm1, %%mm3 \n\t" - "paddw %%mm0, %%mm2 \n\t" - "paddw %%mm1, %%mm3 \n\t" - "psrlw $2, %%mm2 \n\t" - "psrlw $2, %%mm3 \n\t" - "packsswb %%mm3, %%mm2 \n\t" - "movq %%mm2, (%%"REG_D") \n\t" - "add $8, %%"REG_D" \n\t" - "decl %%ecx \n\t" - "jnz 3b \n\t" - : "=S"(crap1), "=D"(crap2) - : "c"(w>>3), "S"(s), "D"(d), "a"((long)ssd) - ); - for (j=w-(w&7); j>2; - d += ds; - s += ss; - } - if (!up) fast_memcpy(d, s, w); - __asm__ volatile("emms \n\t" : : : "memory"); -} - -#if HAVE_EBX_AVAILABLE -static void qpel_4tap_MMX(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up) -{ - int i, j, ssd=ss; - static const short filter[] = { - 29, 29, 29, 29, 110, 110, 110, 110, - 9, 9, 9, 9, 3, 3, 3, 3, - 64, 64, 64, 64 }; - int crap1, crap2; - if (up) { - ssd = -ss; - fast_memcpy(d, s, w); - d += ds; s += ss; - } - for (j=0; j>2; - d += ds; s += ss; - for (i=h-3; i; i--) { - __asm__ volatile( - "pxor %%mm0, %%mm0 \n\t" - "movq (%%"REG_d"), %%mm4 \n\t" - "movq 8(%%"REG_d"), %%mm5 \n\t" - "movq 16(%%"REG_d"), %%mm6 \n\t" - "movq 24(%%"REG_d"), %%mm7 \n\t" - "4: \n\t" - - "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t" - "movq (%%"REG_S"), %%mm2 \n\t" - "movq (%%"REG_S",%%"REG_b"), %%mm3 \n\t" - "punpcklbw %%mm0, %%mm1 \n\t" - "punpcklbw %%mm0, %%mm2 \n\t" - "pmullw %%mm4, %%mm1 \n\t" - "punpcklbw %%mm0, %%mm3 \n\t" - "pmullw %%mm5, %%mm2 \n\t" - "paddusw %%mm2, %%mm1 \n\t" - "pmullw %%mm6, %%mm3 \n\t" - "movq (%%"REG_S",%%"REG_a",2), %%mm2 \n\t" - "psubusw %%mm3, %%mm1 \n\t" - "punpcklbw %%mm0, %%mm2 \n\t" - "pmullw %%mm7, %%mm2 \n\t" - "psubusw %%mm2, %%mm1 \n\t" - "psrlw $7, %%mm1 \n\t" - - "movq (%%"REG_S",%%"REG_a"), %%mm2 \n\t" - "movq (%%"REG_S"), %%mm3 \n\t" - "punpckhbw %%mm0, %%mm2 \n\t" - "punpckhbw %%mm0, %%mm3 \n\t" - "pmullw %%mm4, %%mm2 \n\t" - "pmullw %%mm5, %%mm3 \n\t" - "paddusw %%mm3, %%mm2 \n\t" - "movq (%%"REG_S",%%"REG_b"), %%mm3 \n\t" - "punpckhbw %%mm0, %%mm3 \n\t" - "pmullw %%mm6, %%mm3 \n\t" - "psubusw %%mm3, %%mm2 \n\t" - "movq (%%"REG_S",%%"REG_a",2), %%mm3 \n\t" - "punpckhbw %%mm0, %%mm3 \n\t" - "add $8, %%"REG_S" \n\t" - "pmullw %%mm7, %%mm3 \n\t" - "psubusw %%mm3, %%mm2 \n\t" - "psrlw $7, %%mm2 \n\t" - - "packuswb %%mm2, %%mm1 \n\t" - "movq %%mm1, (%%"REG_D") \n\t" - "add $8, %%"REG_D" \n\t" - "decl %%ecx \n\t" - "jnz 4b \n\t" - : "=S"(crap1), "=D"(crap2) - : "c"(w>>3), "S"(s), "D"(d), "a"((long)ssd), "b"((long)-ssd), "d"(filter) - ); - for (j=w-(w&7); j>7; - d += ds; - s += ss; - } - for (j=0; j>2; - d += ds; s += ss; - if (!up) fast_memcpy(d, s, w); - __asm__ volatile("emms \n\t" : : : "memory"); -} -#endif /* HAVE_EBX_AVAILABLE */ -#endif - -static inline int clamp(int a) -{ - // If a<512, this is equivalent to: - // return (a<0) ? 0 : ( (a>255) ? 255 : a); - return (~(a>>31)) & (a | ((a<<23)>>31)); -} - -static void qpel_li_C(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up) -{ - int i, j, ssd=ss; - if (up) { - ssd = -ss; - fast_memcpy(d, s, w); - d += ds; - s += ss; - } - for (i=h-1; i; i--) { - for (j=0; j>2; - d += ds; - s += ss; - } - if (!up) fast_memcpy(d, s, w); -} - -static void qpel_4tap_C(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up) -{ - int i, j, ssd=ss; - if (up) { - ssd = -ss; - fast_memcpy(d, s, w); - d += ds; s += ss; - } - for (j=0; j>2; - d += ds; s += ss; - for (i=h-3; i; i--) { - for (j=0; j>7); - d += ds; s += ss; - } - for (j=0; j>2; - d += ds; s += ss; - if (!up) fast_memcpy(d, s, w); -} - -static void (*qpel_li)(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up); -static void (*qpel_4tap)(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up); - -static int continue_buffered_image(struct vf_instance *vf); - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - vf->priv->buffered_mpi = mpi; - vf->priv->buffered_pts = pts; - vf->priv->buffered_i = 0; - return continue_buffered_image(vf); -} - -static int continue_buffered_image(struct vf_instance *vf) -{ - int i=vf->priv->buffered_i; - double pts = vf->priv->buffered_pts; - mp_image_t *mpi = vf->priv->buffered_mpi; - int ret=0; - mp_image_t *dmpi; - void (*qpel)(unsigned char *, unsigned char *, int, int, int, int, int) = NULL; - int bpp=1; - int tff; - - if (i == 0) - vf_queue_frame(vf, continue_buffered_image); - pts += i * .02; // XXX not right - - if (!(mpi->flags & MP_IMGFLAG_PLANAR)) bpp = mpi->bpp/8; - if (vf->priv->parity < 0) { - if (mpi->fields & MP_IMGFIELD_ORDERED) - tff = mpi->fields & MP_IMGFIELD_TOP_FIRST; - else - tff = 1; - } - else tff = (vf->priv->parity&1)^1; - - switch (vf->priv->mode) { - case 0: - for (; i<2; i++) { - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->width, mpi->height/2); - dmpi->planes[0] = mpi->planes[0] + (i^!tff)*mpi->stride[0]; - dmpi->stride[0] = 2*mpi->stride[0]; - if (mpi->flags & MP_IMGFLAG_PLANAR) { - dmpi->planes[1] = mpi->planes[1] + (i^!tff)*mpi->stride[1]; - dmpi->planes[2] = mpi->planes[2] + (i^!tff)*mpi->stride[2]; - dmpi->stride[1] = 2*mpi->stride[1]; - dmpi->stride[2] = 2*mpi->stride[2]; - } - ret |= vf_next_put_image(vf, dmpi, pts); - break; - } - break; - case 1: - for (; i<2; i++) { - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->width, mpi->height); - my_memcpy_pic(dmpi->planes[0] + (i^!tff)*dmpi->stride[0], - mpi->planes[0] + (i^!tff)*mpi->stride[0], - mpi->w*bpp, mpi->h/2, dmpi->stride[0]*2, mpi->stride[0]*2); - deint(dmpi->planes[0], dmpi->stride[0], mpi->planes[0], mpi->stride[0], mpi->w, mpi->h, (i^!tff)); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1] + (i^!tff)*dmpi->stride[1], - mpi->planes[1] + (i^!tff)*mpi->stride[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2] + (i^!tff)*dmpi->stride[2], - mpi->planes[2] + (i^!tff)*mpi->stride[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - deint(dmpi->planes[1], dmpi->stride[1], mpi->planes[1], mpi->stride[1], - mpi->chroma_width, mpi->chroma_height, (i^!tff)); - deint(dmpi->planes[2], dmpi->stride[2], mpi->planes[2], mpi->stride[2], - mpi->chroma_width, mpi->chroma_height, (i^!tff)); - } - ret |= vf_next_put_image(vf, dmpi, pts); - break; - } - break; - case 2: - qpel = qpel_li; - case 3: - // TODO: add 3tap filter - if (!qpel) - qpel = qpel_4tap; - case 4: - if (!qpel) - qpel = qpel_4tap; - - for (; i<2; i++) { - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->width, mpi->height/2); - qpel(dmpi->planes[0], mpi->planes[0] + (i^!tff)*mpi->stride[0], - mpi->w*bpp, mpi->h/2, dmpi->stride[0], mpi->stride[0]*2, (i^!tff)); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - qpel(dmpi->planes[1], - mpi->planes[1] + (i^!tff)*mpi->stride[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1], mpi->stride[1]*2, (i^!tff)); - qpel(dmpi->planes[2], - mpi->planes[2] + (i^!tff)*mpi->stride[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2], mpi->stride[2]*2, (i^!tff)); - } - ret |= vf_next_put_image(vf, dmpi, pts); - break; - } - break; - } - vf->priv->buffered_i = 1; - return ret; -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - /* FIXME - figure out which formats exactly work */ - switch (fmt) { - default: - if (vf->priv->mode == 1) - return 0; - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - switch (vf->priv->mode) { - case 0: - case 2: - case 3: - case 4: - return vf_next_config(vf,width,height/2,d_width,d_height,flags,outfmt); - case 1: - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); - } - return 0; -} - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - struct vf_priv_s *p; - vf->config = config; - vf->put_image = put_image; - vf->query_format = query_format; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); - vf->priv->mode = 4; - vf->priv->parity = -1; - if (args) sscanf(args, "%d:%d", &vf->priv->mode, &vf->priv->parity); - qpel_li = qpel_li_C; - qpel_4tap = qpel_4tap_C; -#if HAVE_MMX - if(gCpuCaps.hasMMX) qpel_li = qpel_li_MMX; -#if HAVE_EBX_AVAILABLE - if(gCpuCaps.hasMMX) qpel_4tap = qpel_4tap_MMX; -#endif -#endif -#if HAVE_MMX2 - if(gCpuCaps.hasMMX2) qpel_li = qpel_li_MMX2; -#endif - return 1; -} - -const vf_info_t vf_info_tfields = { - "temporal field separation", - "tfields", - "Rich Felker", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_tile.c b/libmpcodecs/vf_tile.c deleted file mode 100644 index 0b5dac1559..0000000000 --- a/libmpcodecs/vf_tile.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * filter to tile a serie of image in a single, bigger, image - * - * The parameters are: - * - * xtile: number of tile on the x axis (5) - * ytile: number of tile on the y axis (5) - * xytile: when write the image, it can be different then xtile * ytile - * (for example you can write 8 * 7 tile, writing the file every - * 50 frame, to have one image every 2 seconds @ 25 fps ). - * start: pixel at the start (x/y), default 2 - * delta: pixel between 2 tile, (x/y), default 4 - * - * For example a valid command line is: - * ... -vf tile=10:5:-1:4:8 ... - * that make images of 10 * 5 tiles, with 4 pixel at the beginning and - * 8 pixel between tiles. - * - * The default command is: - * ... -vf tile=5:5:25:2:4 - * - * If you omit a parameter or put a value less then 0, the default is used. - * ... -vf tile=10:5::-1:10 - * - * You can also stop when you're ok - * ... -vf tile=10:5 - * (and this is probably the option you will use more often ...) - * - * Probably is good to put the scale filter before the tile :-) - * - * copyright (c) 2003 Daniele Forghieri ( guru@digitalfantasy.it ) - * - * This file is part of MPlayer. - * - * 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. - */ - -// strtoi memcpy_pic - -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/fastmemcpy.h" - -/* private data */ -struct vf_priv_s { - /* configuration data */ - /* Number on hor/ver tiles */ - int xtile; - int ytile; - /* When write the whole frame (default = xtile * ytile) */ - int xytile; - /* pixel at start / end (default = 4) */ - int start; - /* pixel between image (default = 2) */ - int delta; -// /* Background color, in destination format */ -// int bkgSet; - - /* Work data */ - int frame_cur; - double start_pts; -}; - - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - struct vf_priv_s *priv; - int xw; - int yh; - - /* Calculate new destination size */ - priv = vf->priv; - xw = priv->start * 2 + - priv->xtile * width + - (priv->xtile - 1) * priv->delta; - yh = priv->start * 2 + - priv->ytile * height + - (priv->ytile - 1) * priv->delta; - - mp_msg(MSGT_VFILTER,MSGL_V,"vf_tile:config size set to %d * %d\n", xw, yh); - - return vf_next_config(vf, xw, yh, xw, yh, flags, outfmt); -} - -/* Filter handler */ -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - struct vf_priv_s *priv; - int t; - int xw; - int yh; - int xi; - int yi; - int by; - int dw; - - /* Calculate new size */ - priv = vf->priv; - xw = priv->start * 2 + - priv->xtile * mpi->w + - (priv->xtile - 1) * priv->delta; - yh = priv->start * 2 + - priv->ytile * mpi->h+ - (priv->ytile - 1) * priv->delta; - - /* Get the big image! */ - dmpi=vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE, - xw, yh); - - /* bytes x pixel & bytes x line */ - if (mpi->flags & MP_IMGFLAG_PLANAR) { - by = 1; - dw = mpi->w; - } - else { - by = (mpi->bpp + 7) / 8; - dw = mpi->w * by; - } - /* Index position */ - t = priv->frame_cur % priv->xytile; -// if ((t == 0) && (bkg != 0)) { -// /* First frame, delete the background */ -// -// } - if (t == 0) - priv->start_pts = pts; - - /* Position of image */ - xi = priv->start + (mpi->w + priv->delta) * (t % priv->xtile); - yi = priv->start + (mpi->h + priv->delta) * (t / priv->xtile); - - /* Copy first (or only) plane */ - memcpy_pic( dmpi->planes[0] + xi * by + yi * dmpi->stride[0], - mpi->planes[0], - dw, - mpi->h, - dmpi->stride[0], - mpi->stride[0]); - - if (mpi->flags & MP_IMGFLAG_PLANAR) { - /* Copy the other 2 planes */ - memcpy_pic( dmpi->planes[1] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[1], - mpi->planes[1], - mpi->chroma_width, - mpi->chroma_height, - dmpi->stride[1], - mpi->stride[1]); - memcpy_pic( dmpi->planes[2] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[2], - mpi->planes[2], - mpi->chroma_width, - mpi->chroma_height, - dmpi->stride[2], - mpi->stride[2]); - } - - /* Increment current frame */ - ++priv->frame_cur; - - if (t == priv->xytile - 1) { - /* Display the composition */ - dmpi->width = xw; - dmpi->height = yh; - return vf_next_put_image(vf, dmpi, priv->start_pts); - } - else { - /* Skip the frame */ - return 0; - } -} - -static void uninit(struct vf_instance *vf) -{ - /* free local data */ - free(vf->priv); -} - -/* rgb/bgr 12->32 supported & some Yxxx */ -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - switch (fmt) { - /* rgb 12...32 bit */ - case IMGFMT_RGB12: - case IMGFMT_RGB15: - case IMGFMT_RGB16: - case IMGFMT_RGB24: - case IMGFMT_RGB32: - /* bgr 12...32 bit */ - case IMGFMT_BGR12: - case IMGFMT_BGR15: - case IMGFMT_BGR16: - case IMGFMT_BGR24: - case IMGFMT_BGR32: - /* Various Yxxx Formats */ - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - case IMGFMT_YUY2: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_IYUV: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -/* Get an integer from the string pointed by s, adjusting s. - * If the value is less then 0 def_val is used. - * Return 0 for ok - * - * Look below ( in vf_open(...) ) for a use ... - */ -static int parse_int(char **s, int *rt, int def_val) -{ - - int t = 0; - - if (**s) { - /* Get value (dec, hex or octal) */ - t = strtol( *s, s, 0 ); - - /* Use default */ - if (t < 0) { - t = def_val; - } - - if (**s == ':') { - /* Point to next character (problably a digit) */ - ++(*s); - } - else if (**s != '\0') { - /* Error, we got some wrong char */ - return 1; - } - } - else { - t = def_val; - } - - *rt = t; - return 0; - -} - -/* Main entry funct for the filter */ -static int vf_open(vf_instance_t *vf, char *args) -{ - struct vf_priv_s *p; - int er; - - vf->put_image = put_image; - vf->query_format = query_format; - vf->config = config; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - /* Private data */ - vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); - if (p == NULL) { - return 0; - } - - if (args == NULL) { - /* Use the default */ - args = ""; - } - /* Parse all the arguments */ - er = parse_int( &args, &p->xtile, 5 ); - er |= parse_int( &args, &p->ytile, 5 ); - er |= parse_int( &args, &p->xytile, 0 ); - er |= parse_int( &args, &p->start, 2 ); - er |= parse_int( &args, &p->delta, 4 ); -// er |= parse_int( &args, &p->bkgSet, 0 ); - - if (er) { - mp_tmsg(MSGT_VFILTER, MSGL_ERR, "[VF_FRAMESTEP] Error parsing argument.\n"); - return 0; - } - /* Load some default */ - if ((p->xytile <= 0) || (p->xytile > p->xtile * p->ytile)) { - p->xytile = p->xtile * p->ytile; - } - - /* Say what happen: use mp_msg(...)? */ - if ( mp_msg_test(MSGT_VFILTER,MSGL_V) ) { - printf("vf_tile: tiling %d * %d, output every %d frames\n", - p->xtile, - p->ytile, - p->xytile); - printf("vf_tile: start pixel %d, delta pixel %d\n", - p->start, - p->delta); -// printf("vf_tile: background 0x%x\n", -// p->bkgSet); - } - return 1; -} - -const vf_info_t vf_info_tile = { - "Make a single image tiling x/y images", - "tile", - "Daniele Forghieri", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_tinterlace.c b/libmpcodecs/vf_tinterlace.c deleted file mode 100644 index 2583d431e9..0000000000 --- a/libmpcodecs/vf_tinterlace.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2003 Michael Zucchi - * - * This file is part of MPlayer. - * - * 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 -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/fastmemcpy.h" - -struct vf_priv_s { - int mode; - int frame; - mp_image_t *dmpi; -}; - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - int ret = 0; - mp_image_t *dmpi; - - switch (vf->priv->mode) { - case 0: - dmpi = vf->priv->dmpi; - if (dmpi == NULL) { - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE, - mpi->width, mpi->height*2); - - vf->priv->dmpi = dmpi; - - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, - dmpi->stride[0]*2, mpi->stride[0]); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[1]*2, mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[2]*2, mpi->stride[2]); - } - } else { - vf->priv->dmpi = NULL; - - memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h, - dmpi->stride[0]*2, mpi->stride[0]); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[1]*2, mpi->stride[1]); - memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[2]*2, mpi->stride[2]); - } - ret = vf_next_put_image(vf, dmpi, pts); - } - break; - case 1: - if (vf->priv->frame & 1) - ret = vf_next_put_image(vf, mpi, pts); - break; - case 2: - if ((vf->priv->frame & 1) == 0) - ret = vf_next_put_image(vf, mpi, pts); - break; - case 3: - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->width, mpi->height*2); - /* fixme, just clear alternate lines */ - vf_mpi_clear(dmpi, 0, 0, dmpi->w, dmpi->h); - if ((vf->priv->frame & 1) == 0) { - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, - dmpi->stride[0]*2, mpi->stride[0]); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[1]*2, mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[2]*2, mpi->stride[2]); - } - } else { - memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h, - dmpi->stride[0]*2, mpi->stride[0]); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[1]*2, mpi->stride[1]); - memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height, - dmpi->stride[2]*2, mpi->stride[2]); - } - } - ret = vf_next_put_image(vf, dmpi, pts); - break; - case 4: - // Interleave even lines (only) from Frame 'i' with odd - // lines (only) from Frame 'i+1', halving the Frame - // rate and preserving image height. - - dmpi = vf->priv->dmpi; - - // @@ Need help: Should I set dmpi->fields to indicate - // that the (new) frame will be interlaced!? E.g. ... - // dmpi->fields |= MP_IMGFIELD_INTERLACED; - // dmpi->fields |= MP_IMGFIELD_TOP_FIRST; - // etc. - - if (dmpi == NULL) { - dmpi = vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE, - mpi->width, mpi->height); - - vf->priv->dmpi = dmpi; - - my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1], mpi->planes[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2], mpi->planes[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - } else { - vf->priv->dmpi = NULL; - - my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0], - mpi->planes[0]+mpi->stride[0], - mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1], - mpi->planes[1]+mpi->stride[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2], - mpi->planes[2]+mpi->stride[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - ret = vf_next_put_image(vf, dmpi, pts); - } - break; - } - - vf->priv->frame++; - - return ret; -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - /* FIXME - figure out which other formats work */ - switch (fmt) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - return vf_next_query_format(vf, fmt); - } - return 0; -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - switch (vf->priv->mode) { - case 0: - case 3: - return vf_next_config(vf,width,height*2,d_width,d_height*2,flags,outfmt); - case 1: /* odd frames */ - case 2: /* even frames */ - case 4: /* alternate frame (height-preserving) interlacing */ - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); - } - return 0; -} - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - struct vf_priv_s *p; - vf->config = config; - vf->put_image = put_image; - vf->query_format = query_format; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); - vf->priv->mode = 0; - if (args) - sscanf(args, "%d", &vf->priv->mode); - vf->priv->frame = 0; - return 1; -} - -const vf_info_t vf_info_tinterlace = { - "temporal field interlacing", - "tinterlace", - "Michael Zucchi", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_uspp.c b/libmpcodecs/vf_uspp.c deleted file mode 100644 index 8f6dfd25ee..0000000000 --- a/libmpcodecs/vf_uspp.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (C) 2005 Michael Niedermayer - * - * This file is part of MPlayer. - * - * 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 -#include -#include -#include -#include -#include - -#include -#include - -#include "config.h" - -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libvo/fastmemcpy.h" - -#define XMIN(a,b) ((a) < (b) ? (a) : (b)) - -#define BLOCK 16 - -//===========================================================================// -static const uint8_t __attribute__((aligned(8))) dither[8][8]={ -{ 0*4, 48*4, 12*4, 60*4, 3*4, 51*4, 15*4, 63*4, }, -{ 32*4, 16*4, 44*4, 28*4, 35*4, 19*4, 47*4, 31*4, }, -{ 8*4, 56*4, 4*4, 52*4, 11*4, 59*4, 7*4, 55*4, }, -{ 40*4, 24*4, 36*4, 20*4, 43*4, 27*4, 39*4, 23*4, }, -{ 2*4, 50*4, 14*4, 62*4, 1*4, 49*4, 13*4, 61*4, }, -{ 34*4, 18*4, 46*4, 30*4, 33*4, 17*4, 45*4, 29*4, }, -{ 10*4, 58*4, 6*4, 54*4, 9*4, 57*4, 5*4, 53*4, }, -{ 42*4, 26*4, 38*4, 22*4, 41*4, 25*4, 37*4, 21*4, }, -}; - -static const uint8_t offset[511][2]= { -{ 0, 0}, -{ 0, 0}, { 8, 8}, -{ 0, 0}, { 4, 4}, {12, 8}, { 8,12}, -{ 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14}, - -{ 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14}, -{ 5, 1}, {15, 3}, { 9, 5}, { 3, 7}, {13, 9}, { 7,11}, { 1,13}, {11,15}, - -{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, -{ 2, 2}, {10, 2}, { 2,10}, {10,10}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, -{ 4, 4}, {12, 4}, { 4,12}, {12,12}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, -{ 6, 6}, {14, 6}, { 6,14}, {14,14}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, - -{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, -{ 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, -{ 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 2}, {15, 2}, { 7,10}, {15,10}, -{ 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 3}, {14, 3}, { 6,11}, {14,11}, -{ 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 4}, {12, 4}, { 4,12}, {12,12}, -{ 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 5}, {13, 5}, { 5,13}, {13,13}, -{ 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 6}, {15, 6}, { 7,14}, {15,14}, -{ 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, - -{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, -{ 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, -{ 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, -{ 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, -{ 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10}, -{ 2, 4}, {10, 4}, { 2,12}, {10,12}, { 2, 6}, {10, 6}, { 2,14}, {10,14}, -{ 3, 1}, {11, 1}, { 3, 9}, {11, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11}, -{ 3, 5}, {11, 5}, { 3,13}, {11,13}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, -{ 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 4, 2}, {12, 2}, { 4,10}, {12,10}, -{ 4, 4}, {12, 4}, { 4,12}, {12,12}, { 4, 6}, {12, 6}, { 4,14}, {12,14}, -{ 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, -{ 5, 5}, {13, 5}, { 5,13}, {13,13}, { 5, 7}, {13, 7}, { 5,15}, {13,15}, -{ 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 6, 2}, {14, 2}, { 6,10}, {14,10}, -{ 6, 4}, {14, 4}, { 6,12}, {14,12}, { 6, 6}, {14, 6}, { 6,14}, {14,14}, -{ 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, -{ 7, 5}, {15, 5}, { 7,13}, {15,13}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, - -{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 6, 6}, {14, 6}, { 6,14}, {14,14}, { 2, 6}, {10, 6}, { 2,14}, {10,14}, { 6, 2}, {14, 2}, { 6,10}, {14,10}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, { 4, 6}, {12, 6}, { 4,14}, {12,14}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, { 4, 2}, {12, 2}, { 4,10}, {12,10}, { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 6, 4}, {14, 4}, { 6,12}, {14,12}, { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 5}, {13, 5}, { 5,13}, {13,13}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, { 5, 7}, {13, 7}, { 5,15}, {13,15}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, { 3, 1}, {11, 1}, { 3, 9}, {11, 9}, { 7, 5}, {15, 5}, { 7,13}, {15,13}, { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 0, 1}, { 8, 1}, { 0, 9}, { 8, 9}, { 4, 5}, {12, 5}, { 4,13}, {12,13}, { 0, 5}, { 8, 5}, { 0,13}, { 8,13}, { 4, 1}, {12, 1}, { 4, 9}, {12, 9}, { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 3}, {14, 3}, { 6,11}, {14,11}, { 0, 3}, { 8, 3}, { 0,11}, { 8,11}, { 4, 7}, {12, 7}, { 4,15}, {12,15}, { 0, 7}, { 8, 7}, { 0,15}, { 8,15}, { 4, 3}, {12, 3}, { 4,11}, {12,11}, { 2, 1}, {10, 1}, { 2, 9}, {10, 9}, { 6, 5}, {14, 5}, { 6,13}, {14,13}, { 2, 5}, {10, 5}, { 2,13}, {10,13}, { 6, 1}, {14, 1}, { 6, 9}, {14, 9}, { 1, 0}, { 9, 0}, { 1, 8}, { 9, 8}, { 5, 4}, {13, 4}, { 5,12}, {13,12}, { 1, 4}, { 9, 4}, { 1,12}, { 9,12}, { 5, 0}, {13, 0}, { 5, 8}, {13, 8}, { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 6}, {15, 6}, { 7,14}, {15,14}, { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 2}, {15, 2}, { 7,10}, {15,10}, { 1, 2}, { 9, 2}, { 1,10}, { 9,10}, { 5, 6}, {13, 6}, { 5,14}, {13,14}, { 1, 6}, { 9, 6}, { 1,14}, { 9,14}, { 5, 2}, {13, 2}, { 5,10}, {13,10}, { 3, 0}, {11, 0}, { 3, 8}, {11, 8}, { 7, 4}, {15, 4}, { 7,12}, {15,12}, { 3, 4}, {11, 4}, { 3,12}, {11,12}, { 7, 0}, {15, 0}, { 7, 8}, {15, 8}, -}; - -struct vf_priv_s { - int log2_count; - int qp; - int mode; - int mpeg2; - int temp_stride[3]; - uint8_t *src[3]; - int16_t *temp[3]; - int outbuf_size; - uint8_t *outbuf; - AVCodecContext *avctx_enc[BLOCK*BLOCK]; - AVFrame *frame; - AVFrame *frame_dec; -}; - -static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){ - int y, x; - -#define STORE(pos) \ - temp= ((src[x + y*src_stride + pos]<>8;\ - if(temp & 0x100) temp= ~(temp>>31);\ - dst[x + y*dst_stride + pos]= temp; - - for(y=0; ylog2_count; - - for(i=0; i<3; i++){ - int is_chroma= !!i; - int w= width >>is_chroma; - int h= height>>is_chroma; - int stride= p->temp_stride[i]; - int block= BLOCK>>is_chroma; - - if (!src[i] || !dst[i]) - continue; // HACK avoid crash for Y8 colourspace - for(y=0; ysrc[i] + index, src[i] + y*src_stride[i], w); - for(x=0; xsrc[i][index - x - 1]= p->src[i][index + x ]; - p->src[i][index + w + x ]= p->src[i][index + w - x - 1]; - } - } - for(y=0; ysrc[i] + ( block-1-y)*stride, p->src[i] + ( y+block )*stride, stride); - fast_memcpy(p->src[i] + (h+block +y)*stride, p->src[i] + (h-y+block-1)*stride, stride); - } - - p->frame->linesize[i]= stride; - memset(p->temp[i], 0, (h+2*block)*stride*sizeof(int16_t)); - } - - if(p->qp) - p->frame->quality= p->qp * FF_QP2LAMBDA; - else - p->frame->quality= norm_qscale(qp_store[0], p->mpeg2) * FF_QP2LAMBDA; -// init per MB qscale stuff FIXME - - for(i=0; iframe->data[0]= p->src[0] + x1 + y1 * p->frame->linesize[0]; - p->frame->data[1]= p->src[1] + x1/2 + y1/2 * p->frame->linesize[1]; - p->frame->data[2]= p->src[2] + x1/2 + y1/2 * p->frame->linesize[2]; - - avcodec_encode_video(p->avctx_enc[i], p->outbuf, p->outbuf_size, p->frame); - p->frame_dec = p->avctx_enc[i]->coded_frame; - - offset= (BLOCK-x1) + (BLOCK-y1)*p->frame_dec->linesize[0]; - //FIXME optimize - for(y=0; ytemp[0][ x + y*p->temp_stride[0] ] += p->frame_dec->data[0][ x + y*p->frame_dec->linesize[0] + offset ]; - } - } - offset= (BLOCK/2-x1/2) + (BLOCK/2-y1/2)*p->frame_dec->linesize[1]; - for(y=0; ytemp[1][ x + y*p->temp_stride[1] ] += p->frame_dec->data[1][ x + y*p->frame_dec->linesize[1] + offset ]; - p->temp[2][ x + y*p->temp_stride[2] ] += p->frame_dec->data[2][ x + y*p->frame_dec->linesize[2] + offset ]; - } - } - } - - for(j=0; j<3; j++){ - int is_chroma= !!j; - if (!dst[j]) - continue; // HACK avoid crash for Y8 colourspace - store_slice_c(dst[j], p->temp[j], dst_stride[j], p->temp_stride[j], width>>is_chroma, height>>is_chroma, 8-p->log2_count); - } -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - int i; - AVCodec *enc= avcodec_find_encoder(CODEC_ID_SNOW); - - for(i=0; i<3; i++){ - int is_chroma= !!i; - int w= ((width + 4*BLOCK-1) & (~(2*BLOCK-1)))>>is_chroma; - int h= ((height + 4*BLOCK-1) & (~(2*BLOCK-1)))>>is_chroma; - - vf->priv->temp_stride[i]= w; - vf->priv->temp[i]= malloc(vf->priv->temp_stride[i]*h*sizeof(int16_t)); - vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t)); - } - for(i=0; i< (1<priv->log2_count); i++){ - AVCodecContext *avctx_enc; - - avctx_enc = vf->priv->avctx_enc[i] = avcodec_alloc_context3(enc); - avctx_enc->width = width + BLOCK; - avctx_enc->height = height + BLOCK; - avctx_enc->time_base= (AVRational){1,25}; // meaningless - avctx_enc->gop_size = 300; - avctx_enc->max_b_frames= 0; - avctx_enc->pix_fmt = PIX_FMT_YUV420P; - avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY; - avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; - avctx_enc->global_quality= 123; - int res = avcodec_open2(avctx_enc, enc, NULL); - assert(res >= 0); - } - vf->priv->frame= avcodec_alloc_frame(); - vf->priv->frame_dec= avcodec_alloc_frame(); - - vf->priv->outbuf_size= (width + BLOCK)*(height + BLOCK)*10; - vf->priv->outbuf= malloc(vf->priv->outbuf_size); - - return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi){ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // no DR, so get a new image! hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->width,mpi->height); - vf_clone_mpi_attributes(dmpi, mpi); - }else{ - dmpi=vf->dmpi; - } - - vf->priv->mpeg2= mpi->qscale_type; - if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){ - if(mpi->qscale || vf->priv->qp){ - filter(vf->priv, dmpi->planes, mpi->planes, dmpi->stride, mpi->stride, mpi->w, mpi->h, mpi->qscale, mpi->qstride); - }else{ - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]); - memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]); - } - } - -#if HAVE_MMX - if(gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t"); -#endif -#if HAVE_MMX2 - if(gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t"); -#endif - - return vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf){ - int i; - if(!vf->priv) return; - - for(i=0; i<3; i++){ - free(vf->priv->temp[i]); - vf->priv->temp[i]= NULL; - free(vf->priv->src[i]); - vf->priv->src[i]= NULL; - } - for(i=0; ipriv->avctx_enc[i]); - } - - free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_Y800: - case IMGFMT_Y8: - return vf_next_query_format(vf,fmt); - } - return 0; -} - -static int control(struct vf_instance *vf, int request, void* data){ - switch(request){ - case VFCTRL_QUERY_MAX_PP_LEVEL: - return 8; - case VFCTRL_SET_PP_LEVEL: - vf->priv->log2_count= *((unsigned int*)data); - //FIXME we have to realloc a few things here - return CONTROL_TRUE; - } - return vf_next_control(vf,request,data); -} - -static int vf_open(vf_instance_t *vf, char *args){ - - int log2c=-1; - - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->control= control; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - vf->priv->log2_count= 4; - - if (args) sscanf(args, "%d:%d:%d", &log2c, &vf->priv->qp, &vf->priv->mode); - - if( log2c >=0 && log2c <=8 ) - vf->priv->log2_count = log2c; - - if(vf->priv->qp < 0) - vf->priv->qp = 0; - -// #if HAVE_MMX -// if(gCpuCaps.hasMMX){ -// store_slice= store_slice_mmx; -// } -// #endif - - return 1; -} - -const vf_info_t vf_info_uspp = { - "ultra simple/slow postprocess", - "uspp", - "Michael Niedermayer", - "", - vf_open, - NULL -}; diff --git a/libmpcodecs/vf_yuvcsp.c b/libmpcodecs/vf_yuvcsp.c deleted file mode 100644 index 792fcaceb4..0000000000 --- a/libmpcodecs/vf_yuvcsp.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -struct vf_priv_s { - int csp; -}; - -//===========================================================================// - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt); -} - -static inline int clamp_y(int x){ - return (x > 235) ? 235 : (x < 16) ? 16 : x; -} - -static inline int clamp_c(int x){ - return (x > 240) ? 240 : (x < 16) ? 16 : x; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - int i,j; - uint8_t *y_in, *cb_in, *cr_in; - uint8_t *y_out, *cb_out, *cr_out; - - vf->dmpi=vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->width, mpi->height); - - y_in = mpi->planes[0]; - cb_in = mpi->planes[1]; - cr_in = mpi->planes[2]; - - y_out = vf->dmpi->planes[0]; - cb_out = vf->dmpi->planes[1]; - cr_out = vf->dmpi->planes[2]; - - for (i = 0; i < mpi->height; i++) - for (j = 0; j < mpi->width; j++) - y_out[i*vf->dmpi->stride[0]+j] = clamp_y(y_in[i*mpi->stride[0]+j]); - - for (i = 0; i < mpi->chroma_height; i++) - for (j = 0; j < mpi->chroma_width; j++) - { - cb_out[i*vf->dmpi->stride[1]+j] = clamp_c(cb_in[i*mpi->stride[1]+j]); - cr_out[i*vf->dmpi->stride[2]+j] = clamp_c(cr_in[i*mpi->stride[2]+j]); - } - - return vf_next_put_image(vf,vf->dmpi, pts); -} - -//===========================================================================// - -/* -static void uninit(struct vf_instance *vf){ - free(vf->priv); -} -*/ - -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - return 1; - } - return 0; -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; -// vf->uninit=uninit; - vf->query_format=query_format; -// vf->priv=calloc(1, sizeof(struct vf_priv_s)); -// if (args) -// vf->priv->csp = atoi(args); - return 1; -} - -const vf_info_t vf_info_yuvcsp = { - "yuv colorspace converter", - "yuvcsp", - "Alex Beregszaszi", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vf_yvu9.c b/libmpcodecs/vf_yvu9.c deleted file mode 100644 index 1e4e7be561..0000000000 --- a/libmpcodecs/vf_yvu9.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of MPlayer. - * - * 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 -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/fastmemcpy.h" - -//===========================================================================// - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - - if(vf_next_query_format(vf,IMGFMT_YV12)<=0){ - mp_tmsg(MSGT_VFILTER, MSGL_WARN, "%s not supported by next filter/vo :(\n", "YVU9"); - return 0; - } - - return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_YV12); -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - int y,w,h; - - // hope we'll get DR buffer: - dmpi=vf_get_image(vf->next,IMGFMT_YV12, - MP_IMGTYPE_TEMP, 0/*MP_IMGFLAG_ACCEPT_STRIDE*/, - mpi->w, mpi->h); - - for(y=0;yh;y++) - fast_memcpy(dmpi->planes[0]+dmpi->stride[0]*y, - mpi->planes[0]+mpi->stride[0]*y, - mpi->w); - - w=mpi->w/4; h=mpi->h/2; - for(y=0;yplanes[1]+mpi->stride[1]*(y>>1); - unsigned char* d=dmpi->planes[1]+dmpi->stride[1]*y; - int x; - for(x=0;xplanes[2]+mpi->stride[2]*(y>>1); - unsigned char* d=dmpi->planes[2]+dmpi->stride[2]*y; - int x; - for(x=0;xconfig=config; - vf->put_image=put_image; - vf->query_format=query_format; - return 1; -} - -const vf_info_t vf_info_yvu9 = { - "fast YVU9->YV12 conversion", - "yvu9", - "alex", - "", - vf_open, - NULL -}; - -//===========================================================================// diff --git a/libmpcodecs/vqf.h b/libmpcodecs/vqf.h deleted file mode 100644 index 139b578da7..0000000000 --- a/libmpcodecs/vqf.h +++ /dev/null @@ -1,228 +0,0 @@ -/* (c)Copyright 1996-2000 NTT Cyber Space Laboratories */ -/* Released on 2000.05.22 by N. Iwakami */ -/* Modified on 2000.05.25 by N. Iwakami */ -/* Released on 2000.09.06 by N. Iwakami */ - -// Modified for MPlayer on 2004.12.29 - -#ifndef MPLAYER_VQF_H -#define MPLAYER_VQF_H - -#include - -#ifdef _MSC_VER -# ifdef DLL_MODULE -# define DllPort __declspec( dllexport ) -# else -# define DllPort __declspec( dllimport ) -# endif -#else -# define DllPort -#endif - -#ifdef __cplusplus -extern "C" { // only need to import/export C interface if used by C++ source code -#endif - -/************************/ -/*** General settings ***/ -/************************/ -/* Initialization error code */ -enum INIT_ERROR_CODE { - TVQ_NO_ERROR = 0, // no error - TVQ_ERROR, // general - TVQ_ERROR_VERSION, // wrong version - TVQ_ERROR_CHANNEL, // channel setting error - TVQ_ERROR_MODE, // wrong coding mode - TVQ_ERROR_PARAM, // inner parameter setting error - TVQ_ERROR_N_CAN, // wrong number of VQ pre-selection candidates, used only in encoder -}; - -/* version ID */ -#define TVQ_UNKNOWN_VERSION -1 -#define V2 0 -#define V2PP 1 - -#define N_VERSIONS 2 - -/* window types */ -enum WINDOW_TYPE { - ONLY_LONG_WINDOW = 0, - LONG_SHORT_WINDOW, - ONLY_SHORT_WINDOW, - SHORT_LONG_WINDOW, - SHORT_MEDIUM_WINDOW, - MEDIUM_LONG_WINDOW, - LONG_MEDIUM_WINDOW, - MEDIUM_SHORT_WINDOW, - ONLY_MEDIUM_WINDOW, -}; - -/* block types */ -enum BLOCK_TYPE { - BLK_SHORT = 0, - BLK_MEDIUM, - BLK_LONG, - BLK_PPC, -}; -#define N_BTYPE 3 // number of block types -#define N_INTR_TYPE 4 // number of interleave types, enum BLOCK_TYPE is commonly used for detecting interleave types. - -/* maximum number of channels */ -#define N_CH_MAX 2 - -/* type definition of code information interface */ -typedef struct { - /* block type */ - int w_type; - int btype; - - /* FBC info */ - int *segment_sw[ N_CH_MAX ]; - int *band_sw[ N_CH_MAX ]; - int *fg_intensity[ N_CH_MAX ]; - - /* VQ info */ - int *wvq; - - /* BSE info */ - int *fw; - int *fw_alf; - - /* gain info */ - int *pow; - - /* LSP info */ - int *lsp[ N_CH_MAX ]; - - /* PPC info */ - int pit[ N_CH_MAX ]; - int *pls; - int pgain[ N_CH_MAX ]; - - /* EBC info */ - int *bc[ N_CH_MAX ]; - - void *manager; -} INDEX; - -/***********************************************/ -/*** Definitions about program configuration ***/ -/***********************************************/ -/* type definition of tvqConfInfoSubBlock */ -typedef struct { - int sf_sz; // subframe size - int nsf; // number of subframes - int ndiv; // number of division of weighted interleave vector quantization - int ncrb; // number of Bark-scale subbands - int fw_ndiv; // number of division of BSE VQ - int fw_nbit; // number of bits for BSE VQ - int nsubg; // number of sub-blocks for gain coding - int ppc_enable; // PPC switch - int ebc_enable; // EBC switch - int ebc_crb_base; // EBC base band - int ebc_bits; // EBC bits - int fbc_enable; // FBC switch - int fbc_n_segment; // FBC number of segments - int fbc_nband; // FBC number of subbands - int *fbc_crb_tbl; // FBC subband table -} tvqConfInfoSubBlock; - -/* type definition of tvqConfInfo */ -typedef struct { - /* frame configuration */ - int N_CH; - /* window type coding */ - int BITS_WTYPE; - /* LSP coding */ - int LSP_BIT0; - int LSP_BIT1; - int LSP_BIT2; - int LSP_SPLIT; - /* Bark-scale envelope coding */ - int FW_ARSW_BITS; - /* gain coding */ - int GAIN_BITS; - int SUB_GAIN_BITS; - /* pitch excitation */ - int N_DIV_P; - int BASF_BIT; - int PGAIN_BIT; - - /* block type dependent parameters */ - tvqConfInfoSubBlock cfg[N_BTYPE]; - -} tvqConfInfo; - - -/*************************************************/ -/*** Definitions about TwinVQ bitstream header ***/ -/*************************************************/ -//#include "declib_src/tvq_hdr.h" -//#ifndef BUFSIZ -//#define BUFSIZ 1024 -//#endif - -#define KEYWORD_BYTES 4 -#define VERSION_BYTES 8 -#define ELEM_BYTES sizeof(unsigned long) - - -/* - */ -typedef struct { - char ID[KEYWORD_BYTES+VERSION_BYTES+1]; - int size; - /* Common Chunk */ - int channelMode; /* channel mode (mono:0/stereo:1) */ - int bitRate; /* bit rate (kbit/s) */ - int samplingRate; /* sampling rate (44.1 kHz -> 44) */ - int securityLevel; /* security level (always 0) */ - /* Text Chunk */ - char Name[BUFSIZ]; - char Comt[BUFSIZ]; - char Auth[BUFSIZ]; - char Cpyr[BUFSIZ]; - char File[BUFSIZ]; - char Extr[BUFSIZ]; // add by OKAMOTO 99.12.21 - /* Data size chunk*/ - int Dsiz; -} headerInfo; - -// TwinVQ decoder initialization/termination functions -//DllPort int TvqInitialize( headerInfo *setupInfo, INDEX *index, int dispErrorMessageBox ); -//DllPort void TvqTerminate( INDEX *index ); -//DllPort void TvqGetVectorInfo(int *bits0[], int *bits1[]); -//DllPort void TvqResetFrameCounter(void); - -// TwinVQ decoder function -//DllPort void TvqDecodeFrame(INDEX *indexp, float out[]); -//DllPort int TvqWtypeToBtype( int w_type, int *btype ); -//DllPort void TvqUpdateVectorInfo(int varbits, int *ndiv, int bits0[], int bits1[]); -//DllPort void TvqSetFrameCounter( int position ); - -// TwinVQ query functions -//DllPort int TvqCheckVersion(char *versionID); -//DllPort void TvqGetSetupInfo(headerInfo *setupInfo); // setup information -//DllPort void TvqGetConfInfo(tvqConfInfo *cf); // configuration information -//DllPort int TvqGetFrameSize(void); // frame size -//DllPort int TvqGetNumChannels(void); // number of channels -//DllPort int TvqGetBitRate(void); // total bitrate -//DllPort float TvqGetSamplingRate(void); // sampling rate -//DllPort int TvqGetNumFixedBitsPerFrame(void); // number of fixed bits per frame -//DllPort int TvqGetNumFrames(void); // number of decoded frame -//DllPort int TvqGetModuleVersion( char* versionString ); - -#ifdef V2PLUS_SUPPORT -// TwinVQ FB coding tool control -DllPort void TvqFbCountUsedBits(int nbit); // count number of used bits -DllPort float TvqGetFbCurrentBitrate(void); // query average bitrate for the tool -DllPort int TvqGetFbTotalBits(void); // query total number of used bits -#endif - -#ifdef __cplusplus -} -#endif - - -#endif /* MPLAYER_VQF_H */ -- cgit v1.2.3 From 44d1756e33d2196363509aea4ba7a1928f834737 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 14 Oct 2012 18:31:53 +0200 Subject: ad_ffmpeg: add support for planar sample formats FFmpeg and Libav are starting to return a growing number of planar samples when decoding formats that save data like that. In this first implementation planar formats are immediately converted to packed formats. Fututre developments should move to use libavresample. Original work by Nicolas George on mplayer(1). --- libmpcodecs/ad_ffmpeg.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) (limited to 'libmpcodecs') diff --git a/libmpcodecs/ad_ffmpeg.c b/libmpcodecs/ad_ffmpeg.c index c4d7c13941..cca7725490 100644 --- a/libmpcodecs/ad_ffmpeg.c +++ b/libmpcodecs/ad_ffmpeg.c @@ -52,6 +52,7 @@ struct priv { AVCodecContext *avctx; AVFrame *avframe; char *output; + char *output_packed; // used by deplanarize to store packed audio samples int output_left; int unitsize; int previous_data_left; // input demuxer packet data @@ -71,7 +72,7 @@ static int setup_format(sh_audio_t *sh_audio, const AVCodecContext *lavc_context) { int sample_format = sh_audio->sample_format; - switch (lavc_context->sample_fmt) { + switch (av_get_packed_sample_fmt(lavc_context->sample_fmt)) { case AV_SAMPLE_FMT_U8: sample_format = AF_FORMAT_U8; break; case AV_SAMPLE_FMT_S16: sample_format = AF_FORMAT_S16_NE; break; case AV_SAMPLE_FMT_S32: sample_format = AF_FORMAT_S32_NE; break; @@ -218,7 +219,7 @@ static int init(sh_audio_t *sh_audio) if (sh_audio->wf && sh_audio->wf->nAvgBytesPerSec) sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec; - switch (lavc_context->sample_fmt) { + switch (av_get_packed_sample_fmt(lavc_context->sample_fmt)) { case AV_SAMPLE_FMT_U8: case AV_SAMPLE_FMT_S16: case AV_SAMPLE_FMT_S32: @@ -264,6 +265,34 @@ static int control(sh_audio_t *sh, int cmd, void *arg, ...) return CONTROL_UNKNOWN; } +static av_always_inline void deplanarize(struct sh_audio *sh) +{ + struct priv *priv = sh->context; + + size_t bps = av_get_bytes_per_sample(priv->avctx->sample_fmt); + size_t nb_samples = priv->avframe->nb_samples; + size_t channels = priv->avctx->channels; + size_t size = bps * nb_samples * channels; + + if (talloc_get_size(priv->output_packed) != size) + priv->output_packed = + talloc_realloc_size(priv, priv->output_packed, size); + + size_t offset = 0; + unsigned char *output_ptr = priv->output_packed; + unsigned char **src = priv->avframe->data; + + for (size_t s = 0; s < nb_samples; s++) { + for (size_t c = 0; c < channels; c++) { + memcpy(output_ptr, src[c] + offset, bps); + output_ptr += bps; + } + offset += bps; + } + + priv->output = priv->output_packed; +} + static int decode_new_packet(struct sh_audio *sh) { struct priv *priv = sh->context; @@ -320,10 +349,6 @@ static int decode_new_packet(struct sh_audio *sh) priv->previous_data_left = insize - ret; if (!got_frame) return 0; - /* An error is reported later from output format checking, but make - * sure we don't crash by overreading first plane. */ - if (av_sample_fmt_is_planar(avctx->sample_fmt) && avctx->channels > 1) - return 0; uint64_t unitsize = (uint64_t)av_get_bytes_per_sample(avctx->sample_fmt) * avctx->channels; if (unitsize > 100000) @@ -333,7 +358,11 @@ static int decode_new_packet(struct sh_audio *sh) if (output_left > 500000000) abort(); priv->output_left = output_left; - priv->output = priv->avframe->data[0]; + if (av_sample_fmt_is_planar(avctx->sample_fmt) && avctx->channels > 1) { + deplanarize(sh); + } else { + priv->output = priv->avframe->data[0]; + } mp_dbg(MSGT_DECAUDIO, MSGL_DBG2, "Decoded %d -> %d \n", insize, priv->output_left); return 0; -- cgit v1.2.3