diff options
author | wm4 <wm4@nowhere> | 2012-11-01 02:12:47 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2012-11-01 02:12:47 +0100 |
commit | 84829a4ea1903e5db5782b72861fabc503a589cb (patch) | |
tree | 26b4acbaf6dd4b255278dcc67f28bd83357c3b86 /libmpcodecs | |
parent | e45dd051c304dec189d0d4d792a89c2988c3fa71 (diff) | |
parent | f4069259cf7ffd24ac2a5b64e26a386185e94c7b (diff) | |
download | mpv-84829a4ea1903e5db5782b72861fabc503a589cb.tar.bz2 mpv-84829a4ea1903e5db5782b72861fabc503a589cb.tar.xz |
Merge branch 'osd_changes' into master
Conflicts:
DOCS/man/en/options.rst
Diffstat (limited to 'libmpcodecs')
-rw-r--r-- | libmpcodecs/mp_image.c | 63 | ||||
-rw-r--r-- | libmpcodecs/mp_image.h | 26 | ||||
-rw-r--r-- | libmpcodecs/sws_utils.c | 199 | ||||
-rw-r--r-- | libmpcodecs/sws_utils.h | 33 | ||||
-rw-r--r-- | libmpcodecs/vd_ffmpeg.c | 2 | ||||
-rw-r--r-- | libmpcodecs/vf.c | 12 | ||||
-rw-r--r-- | libmpcodecs/vf.h | 6 | ||||
-rw-r--r-- | libmpcodecs/vf_scale.c | 83 | ||||
-rw-r--r-- | libmpcodecs/vf_scale.h | 28 | ||||
-rw-r--r-- | libmpcodecs/vf_screenshot.c | 3 | ||||
-rw-r--r-- | libmpcodecs/vf_sub.c (renamed from libmpcodecs/vf_ass.c) | 221 | ||||
-rw-r--r-- | libmpcodecs/vf_vo.c | 29 | ||||
-rw-r--r-- | libmpcodecs/vfcap.h | 7 |
13 files changed, 364 insertions, 348 deletions
diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c index 412495f096..c0227e4b1d 100644 --- a/libmpcodecs/mp_image.c +++ b/libmpcodecs/mp_image.c @@ -26,11 +26,30 @@ #include "libmpcodecs/img_format.h" #include "libmpcodecs/mp_image.h" +#include "libmpcodecs/sws_utils.h" #include "libvo/fastmemcpy.h" #include "libavutil/mem.h" +#include "libavutil/common.h" void mp_image_alloc_planes(mp_image_t *mpi) { + if (mpi->imgfmt == IMGFMT_BGRA) { + mpi->stride[0]=FFALIGN(mpi->width*4,SWS_MIN_BYTE_ALIGN); + mpi->planes[0]=av_malloc(mpi->stride[0]*mpi->height); + mpi->flags|=MP_IMGFLAG_ALLOCATED; + return; + } + if (mpi->imgfmt == IMGFMT_444P16 || mpi->imgfmt == IMGFMT_444P) { + int bp = mpi->imgfmt == IMGFMT_444P16 ? 2 : 1; + mpi->stride[0]=FFALIGN(mpi->width*bp,SWS_MIN_BYTE_ALIGN); + mpi->stride[1]=mpi->stride[2]=mpi->stride[0]; + int imgsize = mpi->stride[0] * mpi->height; + mpi->planes[0]=av_malloc(imgsize*3); + mpi->planes[1]=mpi->planes[0]+imgsize; + mpi->planes[2]=mpi->planes[1]+imgsize; + mpi->flags|=MP_IMGFLAG_ALLOCATED; + return; + } // IF09 - allocate space for 4. plane delta info - unused if (mpi->imgfmt == IMGFMT_IF09) { mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8+ @@ -40,7 +59,9 @@ void mp_image_alloc_planes(mp_image_t *mpi) { if (!mpi->planes[0]) abort(); //out of memory if (mpi->flags&MP_IMGFLAG_PLANAR) { - int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1; + // FIXME this code only supports same bpp for all planes, and bpp divisible + // by 8. Currently the case for all planar formats. + int bpp = MP_IMAGE_PLANAR_BITS_PER_PIXEL_ON_PLANE(mpi, 0) / 8; // YV12/I420/YVU9/IF09. feel free to add other planar formats here... mpi->stride[0]=mpi->stride[3]=bpp*mpi->width; if(mpi->num_planes > 2){ @@ -82,15 +103,15 @@ mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) { void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) { if(mpi->flags&MP_IMGFLAG_PLANAR){ - memcpy_pic(dmpi->planes[0],mpi->planes[0], mpi->w, mpi->h, + memcpy_pic(dmpi->planes[0],mpi->planes[0], MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 0), mpi->h, dmpi->stride[0],mpi->stride[0]); - memcpy_pic(dmpi->planes[1],mpi->planes[1], mpi->chroma_width, mpi->chroma_height, + memcpy_pic(dmpi->planes[1],mpi->planes[1], MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 1), mpi->chroma_height, dmpi->stride[1],mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, + memcpy_pic(dmpi->planes[2], mpi->planes[2], MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 2), mpi->chroma_height, dmpi->stride[2],mpi->stride[2]); } else { memcpy_pic(dmpi->planes[0],mpi->planes[0], - mpi->w*(dmpi->bpp/8), mpi->h, + MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, 0), mpi->h, dmpi->stride[0],mpi->stride[0]); } } @@ -180,6 +201,9 @@ void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ mpi->flags|=MP_IMGFLAG_SWAPPED; case IMGFMT_YUY2: mpi->chroma_x_shift = 1; + mpi->chroma_y_shift = 1; + mpi->chroma_width=(mpi->width>>1); + mpi->chroma_height=(mpi->height>>1); mpi->bpp=16; mpi->num_planes=1; return; @@ -225,3 +249,32 @@ void free_mp_image(mp_image_t* mpi){ talloc_free(mpi); } +enum mp_csp mp_image_csp(struct mp_image *img) +{ + if (img->colorspace != MP_CSP_AUTO) + return img->colorspace; + return (img->flags & MP_IMGFLAG_YUV) ? MP_CSP_BT_601 : MP_CSP_RGB; +} + +enum mp_csp_levels mp_image_levels(struct mp_image *img) +{ + if (img->levels != MP_CSP_LEVELS_AUTO) + return img->levels; + return (img->flags & MP_IMGFLAG_YUV) ? MP_CSP_LEVELS_TV : MP_CSP_LEVELS_PC; +} + +void mp_image_set_colorspace_details(struct mp_image *image, + struct mp_csp_details *csp) +{ + if (image->flags & MP_IMGFLAG_YUV) { + image->colorspace = csp->format; + if (image->colorspace == MP_CSP_AUTO) + image->colorspace = MP_CSP_BT_601; + image->levels = csp->levels_in; + if (image->levels == MP_CSP_LEVELS_AUTO) + image->levels = MP_CSP_LEVELS_TV; + } else { + image->colorspace = MP_CSP_RGB; + image->levels = MP_CSP_LEVELS_PC; + } +} diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h index 887abc80b6..f2d149bc9d 100644 --- a/libmpcodecs/mp_image.h +++ b/libmpcodecs/mp_image.h @@ -22,7 +22,9 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <inttypes.h> #include "mp_msg.h" +#include "libvo/csputils.h" //--------- codec's requirements (filled by the codec/vf) --------- @@ -109,9 +111,10 @@ typedef struct mp_image { int number; unsigned char bpp; // bits/pixel. NOT depth! for RGB it will be n*8 unsigned int imgfmt; - int width,height; // stored dimensions + int width,height; // internal to vf.c, do not use (stored dimensions) int w,h; // visible dimensions - unsigned char* planes[MP_MAX_PLANES]; + int display_w,display_h; // if set (!= 0), anamorphic size + uint8_t *planes[MP_MAX_PLANES]; int stride[MP_MAX_PLANES]; char * qscale; int qstride; @@ -124,6 +127,8 @@ typedef struct mp_image { int chroma_height; int chroma_x_shift; // horizontal int chroma_y_shift; // vertical + enum mp_csp colorspace; + enum mp_csp_levels levels; int usage_count; /* for private use by filter or vo driver (to store buffer id or dmpi) */ void* priv; @@ -137,4 +142,21 @@ mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt); void mp_image_alloc_planes(mp_image_t *mpi); void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi); +enum mp_csp mp_image_csp(struct mp_image *img); +enum mp_csp_levels mp_image_levels(struct mp_image *img); + +struct mp_csp_details; +void mp_image_set_colorspace_details(struct mp_image *image, + struct mp_csp_details *csp); + +// this macro requires img_format.h to be included too: +#define MP_IMAGE_PLANAR_BITS_PER_PIXEL_ON_PLANE(mpi, p) \ + (IMGFMT_IS_YUVP16((mpi)->imgfmt) ? 16 : 8) +#define MP_IMAGE_BITS_PER_PIXEL_ON_PLANE(mpi, p) \ + (((mpi)->flags & MP_IMGFLAG_PLANAR) \ + ? MP_IMAGE_PLANAR_BITS_PER_PIXEL_ON_PLANE(mpi, p) \ + : (mpi)->bpp) +#define MP_IMAGE_BYTES_PER_ROW_ON_PLANE(mpi, p) \ + ((MP_IMAGE_BITS_PER_PIXEL_ON_PLANE(mpi, p) * ((mpi)->w >> (p ? mpi->chroma_x_shift : 0)) + 7) / 8) + #endif /* MPLAYER_MP_IMAGE_H */ diff --git a/libmpcodecs/sws_utils.c b/libmpcodecs/sws_utils.c new file mode 100644 index 0000000000..4fc5639e55 --- /dev/null +++ b/libmpcodecs/sws_utils.c @@ -0,0 +1,199 @@ +/* + * 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 <assert.h> + +#include <libavutil/opt.h> + +#include "libmpcodecs/sws_utils.h" + +#include "libmpcodecs/mp_image.h" +#include "libmpcodecs/img_format.h" +#include "fmt-conversion.h" +#include "libvo/csputils.h" +#include "mp_msg.h" + +//global sws_flags from the command line +int sws_flags = 2; + +float sws_lum_gblur = 0.0; +float sws_chr_gblur = 0.0; +int sws_chr_vshift = 0; +int sws_chr_hshift = 0; +float sws_chr_sharpen = 0.0; +float sws_lum_sharpen = 0.0; + +//global srcFilter +static SwsFilter *src_filter = NULL; + +void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, + SwsFilter **dstFilterParam) +{ + static int firstTime = 1; + *flags = 0; + + if (firstTime) { + firstTime = 0; + *flags = SWS_PRINT_INFO; + } else if (mp_msg_test(MSGT_VFILTER, MSGL_DBG2)) + *flags = SWS_PRINT_INFO; + + if (src_filter) + sws_freeFilter(src_filter); + + src_filter = sws_getDefaultFilter( + sws_lum_gblur, sws_chr_gblur, + sws_lum_sharpen, sws_chr_sharpen, + sws_chr_hshift, sws_chr_vshift, verbose > 1); + + switch (sws_flags) { + case 0: *flags |= SWS_FAST_BILINEAR; + break; + case 1: *flags |= SWS_BILINEAR; + break; + case 2: *flags |= SWS_BICUBIC; + break; + case 3: *flags |= SWS_X; + break; + case 4: *flags |= SWS_POINT; + break; + case 5: *flags |= SWS_AREA; + break; + case 6: *flags |= SWS_BICUBLIN; + break; + case 7: *flags |= SWS_GAUSS; + break; + case 8: *flags |= SWS_SINC; + break; + case 9: *flags |= SWS_LANCZOS; + break; + case 10: *flags |= SWS_SPLINE; + break; + default: *flags |= SWS_BILINEAR; + break; + } + + *srcFilterParam = src_filter; + *dstFilterParam = NULL; +} + +// will use sws_flags & src_filter (from cmd line) +static struct SwsContext *sws_getContextFromCmdLine2(int srcW, int srcH, + int srcFormat, int dstW, + int dstH, int dstFormat, + int extraflags) +{ + int flags; + SwsFilter *dstFilterParam, *srcFilterParam; + enum PixelFormat dfmt, sfmt; + + dfmt = imgfmt2pixfmt(dstFormat); + sfmt = imgfmt2pixfmt(srcFormat); + if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) + sfmt = PIX_FMT_PAL8; + sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam); + + return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags | + extraflags, srcFilterParam, dstFilterParam, + NULL); +} + +struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, + int dstW, int dstH, + int dstFormat) +{ + return sws_getContextFromCmdLine2(srcW, srcH, srcFormat, dstW, dstH, + dstFormat, + 0); +} + +struct SwsContext *sws_getContextFromCmdLine_hq(int srcW, int srcH, + int srcFormat, int dstW, + int dstH, + int dstFormat) +{ + return sws_getContextFromCmdLine2( + srcW, srcH, srcFormat, dstW, dstH, dstFormat, + SWS_FULL_CHR_H_INT | SWS_FULL_CHR_H_INP | + SWS_ACCURATE_RND | SWS_BITEXACT); +} + +bool mp_sws_supported_format(int imgfmt) +{ + enum PixelFormat av_format = imgfmt2pixfmt(imgfmt); + + return av_format != PIX_FMT_NONE && sws_isSupportedInput(av_format) + && sws_isSupportedOutput(av_format); +} + +static int mp_csp_to_sws_colorspace(enum mp_csp csp) +{ + switch (csp) { + case MP_CSP_BT_601: return SWS_CS_ITU601; + case MP_CSP_BT_709: return SWS_CS_ITU709; + case MP_CSP_SMPTE_240M: return SWS_CS_SMPTE240M; + default: return SWS_CS_DEFAULT; + } +} + +void mp_image_swscale(struct mp_image *dst, struct mp_image *src, + int my_sws_flags) +{ + enum PixelFormat s_fmt = imgfmt2pixfmt(src->imgfmt); + if (src->imgfmt == IMGFMT_RGB8 || src->imgfmt == IMGFMT_BGR8) + s_fmt = PIX_FMT_PAL8; + int s_csp = mp_csp_to_sws_colorspace(mp_image_csp(src)); + int s_range = mp_image_levels(src) == MP_CSP_LEVELS_PC; + + enum PixelFormat d_fmt = imgfmt2pixfmt(dst->imgfmt); + int d_csp = mp_csp_to_sws_colorspace(mp_image_csp(dst)); + int d_range = mp_image_levels(dst) == MP_CSP_LEVELS_PC; + + // Work around libswscale bug #1852 (fixed in ffmpeg commit 8edf9b1fa): + // setting range flags for RGB gives random bogus results. + // Newer libswscale always ignores range flags for RGB. + bool s_yuv = src->flags & MP_IMGFLAG_YUV; + bool d_yuv = dst->flags & MP_IMGFLAG_YUV; + s_range = s_range && s_yuv; + d_range = d_range && d_yuv; + + struct SwsContext *sws = sws_alloc_context(); + + av_opt_set_int(sws, "sws_flags", my_sws_flags, 0); + + av_opt_set_int(sws, "srcw", src->w, 0); + av_opt_set_int(sws, "srch", src->h, 0); + av_opt_set_int(sws, "src_format", s_fmt, 0); + + av_opt_set_int(sws, "dstw", dst->w, 0); + av_opt_set_int(sws, "dsth", dst->h, 0); + av_opt_set_int(sws, "dst_format", d_fmt, 0); + + sws_setColorspaceDetails(sws, sws_getCoefficients(s_csp), s_range, + sws_getCoefficients(d_csp), d_range, + 0, 1 << 16, 1 << 16); + + int res = sws_init_context(sws, NULL, NULL); + assert(res >= 0); + + sws_scale(sws, (const uint8_t *const *) src->planes, src->stride, + 0, src->h, dst->planes, dst->stride); + sws_freeContext(sws); +} + +// vim: ts=4 sw=4 et tw=80 diff --git a/libmpcodecs/sws_utils.h b/libmpcodecs/sws_utils.h new file mode 100644 index 0000000000..a0cc47d850 --- /dev/null +++ b/libmpcodecs/sws_utils.h @@ -0,0 +1,33 @@ +#ifndef MPLAYER_SWS_UTILS_H +#define MPLAYER_SWS_UTILS_H + +#include <stdbool.h> +#include <libswscale/swscale.h> + +struct mp_image; +struct mp_csp_details; + +// libswscale currently requires 16 bytes alignment for row pointers and +// strides. Otherwise, it will print warnings and use slow codepaths. +// Guaranteed to be a power of 2 and > 1. +#define SWS_MIN_BYTE_ALIGN 16 + +void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, + SwsFilter **dstFilterParam); +struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, + int dstW, int dstH, + int dstFormat); +struct SwsContext *sws_getContextFromCmdLine_hq(int srcW, int srcH, + int srcFormat, int dstW, + int dstH, + int dstFormat); +int mp_sws_set_colorspace(struct SwsContext *sws, struct mp_csp_details *csp); + +bool mp_sws_supported_format(int imgfmt); + +void mp_image_swscale(struct mp_image *dst, struct mp_image *src, + int my_sws_flags); + +#endif /* MP_SWS_UTILS_H */ + +// vim: ts=4 sw=4 et tw=80 diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c index 18cad93bad..a358dea014 100644 --- a/libmpcodecs/vd_ffmpeg.c +++ b/libmpcodecs/vd_ffmpeg.c @@ -774,6 +774,8 @@ static struct mp_image *decode(struct sh_video *sh, struct demux_packet *packet, swap_palette(mpi->planes[1]); #endif + mpi->colorspace = sh->colorspace; + mpi->levels = sh->color_range; mpi->qscale = pic->qscale_table; mpi->qstride = pic->qstride; mpi->pict_type = pic->pict_type; diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c index b9937e578c..10b9fa546f 100644 --- a/libmpcodecs/vf.c +++ b/libmpcodecs/vf.c @@ -64,7 +64,7 @@ extern const vf_info_t vf_info_divtc; 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_sub; extern const vf_info_t vf_info_yadif; extern const vf_info_t vf_info_stereo3d; extern const vf_info_t vf_info_dlopen; @@ -102,9 +102,7 @@ static const vf_info_t *const filter_list[] = { &vf_info_delogo, &vf_info_phase, &vf_info_divtc, -#ifdef CONFIG_ASS - &vf_info_ass, -#endif + &vf_info_sub, &vf_info_yadif, &vf_info_stereo3d, &vf_info_dlopen, @@ -541,6 +539,12 @@ void vf_clone_mpi_attributes(mp_image_t *dst, mp_image_t *src) if (dst->width == src->width && dst->height == src->height) { dst->qstride = src->qstride; dst->qscale = src->qscale; + dst->display_w = src->display_w; + dst->display_h = src->display_h; + } + if ((dst->flags & MP_IMGFLAG_YUV) == (src->flags & MP_IMGFLAG_YUV)) { + dst->colorspace = src->colorspace; + dst->levels = src->levels; } } diff --git a/libmpcodecs/vf.h b/libmpcodecs/vf.h index ec8144b22f..4c50f0e9cc 100644 --- a/libmpcodecs/vf.h +++ b/libmpcodecs/vf.h @@ -99,16 +99,14 @@ struct vf_ctrl_screenshot { #define VFCTRL_SET_PP_LEVEL 5 // set postprocessing level #define VFCTRL_SET_EQUALIZER 6 // set color options (brightness,contrast etc) #define VFCTRL_GET_EQUALIZER 8 // get color options (brightness,contrast etc) -#define VFCTRL_DRAW_OSD 7 #define VFCTRL_DUPLICATE_FRAME 11 // For encoding - encode zero-change frame #define VFCTRL_SKIP_NEXT_FRAME 12 // For encoding - drop the next frame that passes thru #define VFCTRL_FLUSH_FRAMES 13 // For encoding - flush delayed frames #define VFCTRL_SCREENSHOT 14 // Take screenshot, arg is vf_ctrl_screenshot -#define VFCTRL_INIT_EOSD 15 // Select EOSD renderer -#define VFCTRL_DRAW_EOSD 16 // Render EOSD */ +#define VFCTRL_INIT_OSD 15 // Filter OSD renderer present? #define VFCTRL_SET_DEINTERLACE 18 // Set deinterlacing status #define VFCTRL_GET_DEINTERLACE 19 // Get deinterlacing status -/* Hack to make the OSD state object available to vf_expand and vf_ass which +/* Hack to make the OSD state object available to vf_sub which * access OSD/subtitle state outside of normal OSD draw time. */ #define VFCTRL_SET_OSD_OBJ 20 #define VFCTRL_SET_YUV_COLORSPACE 22 // arg is struct mp_csp_details* diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c index 71428685ac..5ea62bacbd 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -32,8 +32,7 @@ #include "fmt-conversion.h" #include "mpbswap.h" -#include "libswscale/swscale.h" -#include "vf_scale.h" +#include "libmpcodecs/sws_utils.h" #include "libvo/csputils.h" // VOFLAG_SWSCALE @@ -68,8 +67,6 @@ static struct vf_priv_s { //===========================================================================// -void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam); - static const unsigned int outfmt_list[]={ // YUV: IMGFMT_444P, @@ -647,84 +644,6 @@ static int vf_open(vf_instance_t *vf, char *args){ return 1; } -//global sws_flags from the command line -int sws_flags=2; - -//global srcFilter -static SwsFilter *src_filter= NULL; - -float sws_lum_gblur= 0.0; -float sws_chr_gblur= 0.0; -int sws_chr_vshift= 0; -int sws_chr_hshift= 0; -float sws_chr_sharpen= 0.0; -float sws_lum_sharpen= 0.0; - -void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam) -{ - static int firstTime=1; - *flags=0; - - if(firstTime) - { - firstTime=0; - *flags= SWS_PRINT_INFO; - } - else if( mp_msg_test(MSGT_VFILTER,MSGL_DBG2) ) *flags= SWS_PRINT_INFO; - - if(src_filter) sws_freeFilter(src_filter); - - src_filter= sws_getDefaultFilter( - sws_lum_gblur, sws_chr_gblur, - sws_lum_sharpen, sws_chr_sharpen, - sws_chr_hshift, sws_chr_vshift, verbose>1); - - switch(sws_flags) - { - case 0: *flags|= SWS_FAST_BILINEAR; break; - case 1: *flags|= SWS_BILINEAR; break; - case 2: *flags|= SWS_BICUBIC; break; - case 3: *flags|= SWS_X; break; - case 4: *flags|= SWS_POINT; break; - case 5: *flags|= SWS_AREA; break; - case 6: *flags|= SWS_BICUBLIN; break; - case 7: *flags|= SWS_GAUSS; break; - case 8: *flags|= SWS_SINC; break; - case 9: *flags|= SWS_LANCZOS; break; - case 10:*flags|= SWS_SPLINE; break; - default:*flags|= SWS_BILINEAR; break; - } - - *srcFilterParam= src_filter; - *dstFilterParam= NULL; -} - -// will use sws_flags & src_filter (from cmd line) -static struct SwsContext *sws_getContextFromCmdLine2(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int extraflags) -{ - int flags; - SwsFilter *dstFilterParam, *srcFilterParam; - enum PixelFormat dfmt, sfmt; - - dfmt = imgfmt2pixfmt(dstFormat); - sfmt = imgfmt2pixfmt(srcFormat); - if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = PIX_FMT_PAL8; - sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam); - - return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags | extraflags, srcFilterParam, dstFilterParam, NULL); -} - -struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat) -{ - return sws_getContextFromCmdLine2(srcW, srcH, srcFormat, dstW, dstH, dstFormat, 0); -} - -struct SwsContext *sws_getContextFromCmdLine_hq(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat) -{ - return sws_getContextFromCmdLine2(srcW, srcH, srcFormat, dstW, dstH, dstFormat, - SWS_FULL_CHR_H_INT | SWS_FULL_CHR_H_INP | SWS_ACCURATE_RND | SWS_BITEXACT); -} - /// An example of presets usage static const struct size_preset { char* name; diff --git a/libmpcodecs/vf_scale.h b/libmpcodecs/vf_scale.h deleted file mode 100644 index 575d4f3640..0000000000 --- a/libmpcodecs/vf_scale.h +++ /dev/null @@ -1,28 +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. - */ - -#ifndef MPLAYER_VF_SCALE_H -#define MPLAYER_VF_SCALE_H - -struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat); -struct SwsContext *sws_getContextFromCmdLine_hq(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat); - -struct mp_csp_details; -int mp_sws_set_colorspace(struct SwsContext *sws, struct mp_csp_details *csp); - -#endif /* MPLAYER_VF_SCALE_H */ diff --git a/libmpcodecs/vf_screenshot.c b/libmpcodecs/vf_screenshot.c index 6bfd84d740..693d871e5f 100644 --- a/libmpcodecs/vf_screenshot.c +++ b/libmpcodecs/vf_screenshot.c @@ -27,7 +27,7 @@ #include "img_format.h" #include "mp_image.h" #include "vf.h" -#include "vf_scale.h" +#include "libmpcodecs/sws_utils.h" #include "fmt-conversion.h" #include "libvo/fastmemcpy.h" @@ -141,6 +141,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) image = *vf->priv->image; image.w = vf->priv->image->w; image.h = vf->priv->image->h; + vf_clone_mpi_attributes(&image, mpi); vf->priv->image_callback(vf->priv->image_callback_ctx, &image); vf->priv->store_slices = 0; } diff --git a/libmpcodecs/vf_ass.c b/libmpcodecs/vf_sub.c index f0b2e6ab77..2d5de3a7ba 100644 --- a/libmpcodecs/vf_ass.c +++ b/libmpcodecs/vf_sub.c @@ -35,41 +35,25 @@ #include "mp_image.h" #include "vf.h" #include "sub/sub.h" +#include "sub/dec_sub.h" #include "libvo/fastmemcpy.h" +#include "libvo/csputils.h" #include "m_option.h" #include "m_struct.h" -#include "sub/ass_mp.h" - -#define _r(c) ((c)>>24) -#define _g(c) (((c)>>16)&0xFF) -#define _b(c) (((c)>>8)&0xFF) -#define _a(c) ((c)&0xFF) -#define rgba2y(c) ( (( 263*_r(c) + 516*_g(c) + 100*_b(c)) >> 10) + 16 ) -#define rgba2u(c) ( ((-152*_r(c) - 298*_g(c) + 450*_b(c)) >> 10) + 128 ) -#define rgba2v(c) ( (( 450*_r(c) - 376*_g(c) - 73*_b(c)) >> 10) + 128 ) - - static const struct vf_priv_s { int outh, outw; unsigned int outfmt; - - // 1 = auto-added filter: insert only if chain does not support EOSD already - // 0 = insert always - int auto_insert; + struct mp_csp_details csp; struct osd_state *osd; - double aspect_correction; - - unsigned char *planes[3]; - struct line_limits { - uint16_t start; - uint16_t end; - } *line_limits; -} vf_priv_dflt; + struct mp_osd_res dim; +} vf_priv_dflt = { + .csp = MP_CSP_DETAILS_DEFAULTS, +}; static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, @@ -87,11 +71,17 @@ static int config(struct vf_instance *vf, d_height = d_height * vf->priv->outh / height; } - vf->priv->planes[1] = malloc(vf->priv->outw * vf->priv->outh); - vf->priv->planes[2] = malloc(vf->priv->outw * vf->priv->outh); - vf->priv->line_limits = malloc((vf->priv->outh + 1) / 2 * sizeof(*vf->priv->line_limits)); + double dar = (double)d_width / d_height; + double sar = (double)width / height; - vf->priv->aspect_correction = (double)width / height * d_height / d_width; + vf->priv->dim = (struct mp_osd_res) { + .w = vf->priv->outw, + .h = vf->priv->outh, + .mt = opts->ass_top_margin, + .mb = opts->ass_bottom_margin, + .display_par = sar / dar, + .video_par = dar / sar, + }; return vf_next_config(vf, vf->priv->outw, vf->priv->outh, d_width, d_height, flags, outfmt); @@ -225,153 +215,16 @@ static int prepare_image(struct vf_instance *vf, mp_image_t *mpi) return 0; } -static void update_limits(struct vf_instance *vf, int starty, int endy, - int startx, int endx) -{ - starty >>= 1; - endy = (endy + 1) >> 1; - startx >>= 1; - endx = (endx + 1) >> 1; - for (int i = starty; i < endy; i++) { - struct line_limits *ll = vf->priv->line_limits + i; - if (startx < ll->start) - ll->start = startx; - if (endx > ll->end) - ll->end = endx; - } -} - -/** - * \brief Copy specified rows from render_context.dmpi to render_context.planes, upsampling to 4:4:4 - */ -static void copy_from_image(struct vf_instance *vf) -{ - int pl; - - for (pl = 1; pl < 3; ++pl) { - int dst_stride = vf->priv->outw; - int src_stride = vf->dmpi->stride[pl]; - - unsigned char *src = vf->dmpi->planes[pl]; - unsigned char *dst = vf->priv->planes[pl]; - for (int i = 0; i < (vf->priv->outh + 1) / 2; i++) { - struct line_limits *ll = vf->priv->line_limits + i; - unsigned char *dst_next = dst + dst_stride; - for (int j = ll->start; j < ll->end; j++) { - unsigned char val = src[j]; - dst[j << 1] = val; - dst[(j << 1) + 1] = val; - dst_next[j << 1] = val; - dst_next[(j << 1) + 1] = val; - } - src += src_stride; - dst = dst_next + dst_stride; - } - } -} - -/** - * \brief Copy all previously copied rows back to render_context.dmpi - */ -static void copy_to_image(struct vf_instance *vf) -{ - int pl; - int i, j; - for (pl = 1; pl < 3; ++pl) { - int dst_stride = vf->dmpi->stride[pl]; - int src_stride = vf->priv->outw; - - unsigned char *dst = vf->dmpi->planes[pl]; - unsigned char *src = vf->priv->planes[pl]; - unsigned char *src_next = vf->priv->planes[pl] + src_stride; - for (i = 0; i < vf->priv->outh / 2; ++i) { - for (j = vf->priv->line_limits[i].start; j < vf->priv->line_limits[i].end; j++) { - unsigned val = 0; - val += src[j << 1]; - val += src[(j << 1) + 1]; - val += src_next[j << 1]; - val += src_next[(j << 1) + 1]; - dst[j] = val >> 2; - } - dst += dst_stride; - src = src_next + src_stride; - src_next = src + src_stride; - } - } -} - -static void my_draw_bitmap(struct vf_instance *vf, unsigned char *bitmap, - int bitmap_w, int bitmap_h, int stride, - int dst_x, int dst_y, unsigned color) -{ - unsigned char y = rgba2y(color); - unsigned char u = rgba2u(color); - unsigned char v = rgba2v(color); - unsigned char opacity = 255 - _a(color); - unsigned char *src, *dsty, *dstu, *dstv; - int i, j; - mp_image_t *dmpi = vf->dmpi; - - src = bitmap; - dsty = dmpi->planes[0] + dst_x + dst_y * dmpi->stride[0]; - dstu = vf->priv->planes[1] + dst_x + dst_y * vf->priv->outw; - dstv = vf->priv->planes[2] + dst_x + dst_y * vf->priv->outw; - for (i = 0; i < bitmap_h; ++i) { - for (j = 0; j < bitmap_w; ++j) { - unsigned k = (src[j] * opacity + 255) >> 8; - dsty[j] = (k * y + (255 - k) * dsty[j] + 255) >> 8; - dstu[j] = (k * u + (255 - k) * dstu[j] + 255) >> 8; - dstv[j] = (k * v + (255 - k) * dstv[j] + 255) >> 8; - } - src += stride; - dsty += dmpi->stride[0]; - dstu += vf->priv->outw; - dstv += vf->priv->outw; - } -} - -static int render_frame(struct vf_instance *vf, mp_image_t *mpi, - const ASS_Image *img) -{ - if (img) { - for (int i = 0; i < (vf->priv->outh + 1) / 2; i++) - vf->priv->line_limits[i] = (struct line_limits){65535, 0}; - for (const ASS_Image *im = img; im; im = im->next) - update_limits(vf, im->dst_y, im->dst_y + im->h, - im->dst_x, im->dst_x + im->w); - copy_from_image(vf); - while (img) { - my_draw_bitmap(vf, img->bitmap, img->w, img->h, img->stride, - img->dst_x, img->dst_y, img->color); - img = img->next; - } - copy_to_image(vf); - } - return 0; -} - static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) { struct vf_priv |