summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/mp_image.c34
-rw-r--r--libmpcodecs/mp_image.h10
-rw-r--r--libmpcodecs/sws_utils.c166
-rw-r--r--libmpcodecs/sws_utils.h35
-rw-r--r--libmpcodecs/vf.c6
-rw-r--r--libmpcodecs/vf.h6
-rw-r--r--libmpcodecs/vf_scale.c83
-rw-r--r--libmpcodecs/vf_scale.h28
-rw-r--r--libmpcodecs/vf_screenshot.c2
-rw-r--r--libmpcodecs/vf_sub.c (renamed from libmpcodecs/vf_ass.c)222
-rw-r--r--libmpcodecs/vf_vo.c29
-rw-r--r--libmpcodecs/vfcap.h7
12 files changed, 282 insertions, 346 deletions
diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c
index 412495f096..b7c9017188 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;
diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h
index 6dbe3bfe02..e1cbe7d2cf 100644
--- a/libmpcodecs/mp_image.h
+++ b/libmpcodecs/mp_image.h
@@ -130,4 +130,14 @@ 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);
+// 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..d7500efe2e
--- /dev/null
+++ b/libmpcodecs/sws_utils.c
@@ -0,0 +1,166 @@
+/*
+ * 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 "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);
+}
+
+void mp_image_swscale(struct mp_image *dst,
+ const struct mp_image *src,
+ struct mp_csp_details *csp,
+ int my_sws_flags)
+{
+ enum PixelFormat dfmt, sfmt;
+ dfmt = imgfmt2pixfmt(dst->imgfmt);
+ sfmt = imgfmt2pixfmt(src->imgfmt);
+ if (src->imgfmt == IMGFMT_RGB8 || src->imgfmt == IMGFMT_BGR8)
+ sfmt = PIX_FMT_PAL8;
+
+ struct SwsContext *sws =
+ sws_getContext(src->w, src->h, sfmt, dst->w, dst->h, dfmt,
+ my_sws_flags, NULL, NULL, NULL);
+ struct mp_csp_details mycsp = MP_CSP_DETAILS_DEFAULTS;
+ if (csp)
+ mycsp = *csp;
+ mp_sws_set_colorspace(sws, &mycsp);
+ sws_scale(sws, (const unsigned char *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..70b7d0b7fb
--- /dev/null
+++ b/libmpcodecs/sws_utils.h
@@ -0,0 +1,35 @@
+#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,
+ const struct mp_image *src,
+ struct mp_csp_details *csp,
+ int my_sws_flags);
+
+#endif /* MP_SWS_UTILS_H */
+
+// vim: ts=4 sw=4 et tw=80
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index 6ec932445a..39a720a893 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,
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 eb961d8118..013525694a 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"
diff --git a/libmpcodecs/vf_ass.c b/libmpcodecs/vf_sub.c
index f0b2e6ab77..78f75221cb 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,17 @@ 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_s *priv = vf->priv;
- struct MPOpts *opts = vf->opts;
struct osd_state *osd = priv->osd;
- ASS_Image *images = 0;
- if (pts != MP_NOPTS_VALUE) {
- osd->dim = (struct mp_eosd_res){ .w = vf->priv->outw,
- .h = vf->priv->outh,
- .mt = opts->ass_top_margin,
- .mb = opts->ass_bottom_margin };
- osd->normal_scale = vf->priv->aspect_correction;
- osd->vsfilter_scale = 1;
- osd->sub_pts = pts - osd->sub_offset;
- osd->support_rgba = false;
- struct sub_bitmaps b;
- sub_get_bitmaps(osd, &b);
- images = b.imgs;
- }
prepare_image(vf, mpi);
- render_frame(vf, mpi, images);
+
+ if (pts != MP_NOPTS_VALUE) {
+ osd_draw_on_image(osd, priv->dim, pts, OSD_DRAW_SUB_FILTER, vf->dmpi,
+ &priv->csp);
+ }
return vf_next_put_image(vf, vf->dmpi, pts);
}
@@ -393,19 +247,19 @@ static int control(vf_instance_t *vf, int request, void *data)
case VFCTRL_SET_OSD_OBJ:
vf->priv->osd = data;
break;
- case VFCTRL_INIT_EOSD:
- return CONTROL_TRUE;
- case VFCTRL_DRAW_EOSD:
+ case VFCTRL_INIT_OSD:
return CONTROL_TRUE;
+ case VFCTRL_SET_YUV_COLORSPACE: {
+ struct mp_csp_details colorspace = *(struct mp_csp_details *)data;
+ vf->priv->csp = colorspace;
+ break;
+ }
}
return vf_next_control(vf, request, data);
}
static void uninit(struct vf_instance *vf)
{
- free(vf->priv->planes[1]);
- free(vf->priv->planes[2]);
- free(vf->priv->line_limits);
free(vf->priv);
}
@@ -418,47 +272,37 @@ static const unsigned int fmt_list[] = {
static int vf_open(vf_instance_t *vf, char *args)
{
- int flags;
vf->priv->outfmt = vf_match_csp(&vf->next, fmt_list, IMGFMT_YV12);
- if (vf->priv->outfmt)
- flags = vf_next_query_format(vf, vf->priv->outfmt);
if (!vf->priv->outfmt) {
uninit(vf);
return 0;
- } else if (vf->priv->auto_insert && flags & VFCAP_EOSD) {
- uninit(vf);
- return -1;
}
- if (vf->priv->auto_insert)
- mp_msg(MSGT_ASS, MSGL_INFO, "[ass] auto-open\n");
-
vf->config = config;
vf->query_format = query_format;
vf->uninit = uninit;
vf->control = control;
vf->get_image = get_image;
vf->put_image = put_image;
- vf->default_caps = VFCAP_EOSD | VFCAP_EOSD_FILTER;
+ vf->default_caps = VFCAP_OSD;
return 1;
}
#define ST_OFF(f) M_ST_OFF(struct vf_priv_s, f)
static const m_option_t vf_opts_fields[] = {
- {"auto", ST_OFF(auto_insert), CONF_TYPE_FLAG, 0, 0, 1, NULL},
{NULL, NULL, 0, 0, 0, 0, NULL}
};
static const m_struct_t vf_opts = {
- "ass",
+ "sub",
sizeof(struct vf_priv_s),
&vf_priv_dflt,
vf_opts_fields
};
-const vf_info_t vf_info_ass = {
- "Render ASS/SSA subtitles",
- "ass",
+const vf_info_t vf_info_sub = {
+ "Render subtitles",
+ "sub",
"Evgeniy Stepanov",
"",
vf_open,
diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
index 862cd63492..d11724f881 100644
--- a/libmpcodecs/vf_vo.c
+++ b/libmpcodecs/vf_vo.c
@@ -34,11 +34,9 @@
struct vf_priv_s {
struct vo *vo;
- double scale_ratio;
};
#define video_out (vf->priv->vo)
-static int query_format(struct vf_instance *vf, unsigned int fmt);
static void draw_slice(struct vf_instance *vf, unsigned char **src,
int *stride, int w, int h, int x, int y);
@@ -67,14 +65,12 @@ static int config(struct vf_instance *vf,
if (info->comment && strlen(info->comment) > 0)
mp_msg(MSGT_CPLAYER, MSGL_V, "VO: Comment: %s\n", info->comment);
- // save vo's stride capability for the wanted colorspace:
- vf->default_caps = query_format(vf, outfmt);
- vf->draw_slice = (vf->default_caps & VOCAP_NOSLICES) ? NULL : draw_slice;
-
if (vo_config(video_out, width, height, d_width, d_height, flags, outfmt))
return 0;
- vf->priv->scale_ratio = (double) d_width / d_height * height / width;
+ // save vo's stride capability for the wanted colorspace:
+ vf->default_caps = video_out->default_caps;
+ vf->draw_slice = (vf->default_caps & VOCAP_NOSLICES) ? NULL : draw_slice;
return 1;
}
@@ -94,11 +90,6 @@ static int control(struct vf_instance *vf, int request, void *data)
return vo_control(video_out, VOCTRL_GET_YUV_COLORSPACE, data) == true;
case VFCTRL_SET_YUV_COLORSPACE:
return vo_control(video_out, VOCTRL_SET_YUV_COLORSPACE, data) == true;
- case VFCTRL_DRAW_OSD:
- if (!video_out->config_ok)
- return CONTROL_FALSE; // vo not configured?
- vo_draw_osd(video_out, data);
- return CONTROL_TRUE;
case VFCTRL_SET_EQUALIZER: {
vf_equalizer_t *eq = data;
if (!video_out->config_ok)
@@ -117,20 +108,6 @@ static int control(struct vf_instance *vf, int request, void *data)
};
return vo_control(video_out, VOCTRL_GET_EQUALIZER, &param) == VO_TRUE;
}
- case VFCTRL_DRAW_EOSD: {
- struct osd_state *osd = data;
- osd->support_rgba = vf->default_caps & VFCAP_EOSD_RGBA;
- osd->dim = (struct mp_eosd_res){0};
- if (!video_out->config_ok ||
- vo_control(video_out, VOCTRL_GET_EOSD_RES, &osd->dim) != true)
- return CONTROL_FALSE;
- osd->normal_scale = 1;
- osd->vsfilter_scale = vf->priv->scale_ratio;
- osd->unscaled = vf->default_caps & VFCAP_EOSD_UNSCALED;
- struct sub_bitmaps images;
- sub_get_bitmaps(osd, &images);
- return vo_control(video_out, VOCTRL_DRAW_EOSD, &images) == VO_TRUE;
- }
}
return CONTROL_UNKNOWN;
}
diff --git a/libmpcodecs/vfcap.h b/libmpcodecs/vfcap.h
index aef75840ae..acc7ce31c6 100644
--- a/libmpcodecs/vfcap.h
+++ b/