summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/img_format.c1
-rw-r--r--libmpcodecs/img_format.h2
-rw-r--r--libmpcodecs/mp_image.c7
-rw-r--r--libmpcodecs/mp_image.h2
-rw-r--r--libmpcodecs/vd.c6
-rw-r--r--libmpcodecs/vf.c2
-rw-r--r--libmpcodecs/vf_ass.c50
-rw-r--r--libmpcodecs/vf_gradfun.c56
-rw-r--r--libmpcodecs/vf_scale.c20
-rw-r--r--libmpcodecs/vf_scale.h1
-rw-r--r--libmpcodecs/vf_screenshot.c12
-rw-r--r--libmpcodecs/vf_vo.c44
12 files changed, 124 insertions, 79 deletions
diff --git a/libmpcodecs/img_format.c b/libmpcodecs/img_format.c
index c6d3e82149..033c0a4e3e 100644
--- a/libmpcodecs/img_format.c
+++ b/libmpcodecs/img_format.c
@@ -50,6 +50,7 @@ const char *vo_format_name(int format)
case IMGFMT_BGRA: return "BGRA";
case IMGFMT_ARGB: return "ARGB";
case IMGFMT_RGBA: return "RGBA";
+ case IMGFMT_GBRP: return "Planar GBR 24-bit";
case IMGFMT_YVU9: return "Planar YVU9";
case IMGFMT_IF09: return "Planar IF09";
case IMGFMT_YV12: return "Planar YV12";
diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h
index d4443af2c9..4200282f98 100644
--- a/libmpcodecs/img_format.h
+++ b/libmpcodecs/img_format.h
@@ -49,6 +49,8 @@
#define IMGFMT_BGR24 (IMGFMT_BGR|24)
#define IMGFMT_BGR32 (IMGFMT_BGR|32)
+#define IMGFMT_GBRP (('G'<<24)|('B'<<16)|('R'<<8)|24)
+
#if HAVE_BIGENDIAN
#define IMGFMT_ABGR IMGFMT_RGB32
#define IMGFMT_BGRA (IMGFMT_RGB32|64)
diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c
index 45426eb673..4e20dee119 100644
--- a/libmpcodecs/mp_image.c
+++ b/libmpcodecs/mp_image.c
@@ -119,8 +119,13 @@ void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){
mpi->flags|=MP_IMGFLAG_SWAPPED;
return;
}
- mpi->flags|=MP_IMGFLAG_YUV;
mpi->num_planes=3;
+ if (out_fmt == IMGFMT_GBRP) {
+ mpi->bpp=24;
+ mpi->flags|=MP_IMGFLAG_PLANAR;
+ return;
+ }
+ mpi->flags|=MP_IMGFLAG_YUV;
if (mp_get_chroma_shift(out_fmt, NULL, NULL, NULL)) {
mpi->flags|=MP_IMGFLAG_PLANAR;
mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift, NULL);
diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h
index dd69788f26..6dbe3bfe02 100644
--- a/libmpcodecs/mp_image.h
+++ b/libmpcodecs/mp_image.h
@@ -103,7 +103,7 @@ typedef struct mp_image {
unsigned char bpp; // bits/pixel. NOT depth! for RGB it will be n*8
unsigned int imgfmt;
int width,height; // stored dimensions
- int x,y,w,h; // visible dimensions
+ int w,h; // visible dimensions
unsigned char* planes[MP_MAX_PLANES];
int stride[MP_MAX_PLANES];
char * qscale;
diff --git a/libmpcodecs/vd.c b/libmpcodecs/vd.c
index 5a96e07783..e6ce3e8ff3 100644
--- a/libmpcodecs/vd.c
+++ b/libmpcodecs/vd.c
@@ -358,11 +358,7 @@ int mpcodecs_config_vo2(sh_video_t *sh, int w, int h,
mp_image_t *mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag,
int w, int h)
{
- mp_image_t *mpi =
- vf_get_image(sh->vfilter, sh->outfmt, mp_imgtype, mp_imgflag, w, h);
- if (mpi)
- mpi->x = mpi->y = 0;
- return mpi;
+ return vf_get_image(sh->vfilter, sh->outfmt, mp_imgtype, mp_imgflag, w, h);
}
void mpcodecs_draw_slice(sh_video_t *sh, unsigned char **src, int *stride,
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index f4d6768531..83ae763fba 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -106,6 +106,7 @@ 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;
@@ -140,6 +141,7 @@ static const vf_info_t *const filter_list[] = {
&vf_info_lavc,
&vf_info_lavcdeint,
&vf_info_screenshot,
+ &vf_info_screenshot_force,
&vf_info_fspp,
&vf_info_uspp,
diff --git a/libmpcodecs/vf_ass.c b/libmpcodecs/vf_ass.c
index 82351500b3..4dcddb1d08 100644
--- a/libmpcodecs/vf_ass.c
+++ b/libmpcodecs/vf_ass.c
@@ -61,8 +61,9 @@ static const struct vf_priv_s {
int auto_insert;
struct osd_state *osd;
- ASS_Renderer *renderer_realaspect;
- ASS_Renderer *renderer_vsfilter;
+ ASS_Renderer *renderer;
+
+ double realaspect;
unsigned char *planes[3];
struct line_limits {
@@ -93,14 +94,10 @@ static int config(struct vf_instance *vf,
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));
- if (vf->priv->renderer_realaspect) {
- mp_ass_configure(vf->priv->renderer_realaspect, opts,
- vf->priv->outw, vf->priv->outh, 0);
- mp_ass_configure(vf->priv->renderer_vsfilter, opts,
+ if (vf->priv->renderer) {
+ mp_ass_configure(vf->priv->renderer, opts,
vf->priv->outw, vf->priv->outh, 0);
- ass_set_aspect_ratio(vf->priv->renderer_realaspect,
- (double)width / height * d_height / d_width, 1);
- ass_set_aspect_ratio(vf->priv->renderer_vsfilter, 1, 1);
+ vf->priv->realaspect = (double)width / height * d_height / d_width;
}
return vf_next_config(vf, vf->priv->outw, vf->priv->outh, d_width,
@@ -363,17 +360,16 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
{
struct osd_state *osd = vf->priv->osd;
ASS_Image *images = 0;
- ASS_Renderer *renderer = osd->vsfilter_aspect
+ double scale = osd->vsfilter_aspect
&& vf->opts->ass_vsfilter_aspect_compat
- ? vf->priv->renderer_vsfilter : vf->priv->renderer_realaspect;
- if (sub_visibility && renderer && osd->ass_track
+ ? 1 : vf->priv->realaspect;
+ if (sub_visibility && vf->priv->renderer && osd->ass_track
&& (pts != MP_NOPTS_VALUE)) {
- if (osd->ass_force_reload) {
- mp_ass_reload_options(vf->priv->renderer_realaspect, vf->opts);
- mp_ass_reload_options(vf->priv->renderer_vsfilter, vf->opts);
- }
+ ass_set_aspect_ratio(vf->priv->renderer, scale, 1);
+ if (osd->ass_force_reload)
+ mp_ass_reload_options(vf->priv->renderer, vf->opts);
osd->ass_force_reload = false;
- images = ass_render_frame(renderer, osd->ass_track,
+ images = ass_render_frame(vf->priv->renderer, osd->ass_track,
(pts - osd->sub_offset + sub_delay) * 1000 + .5, NULL);
}
@@ -402,19 +398,13 @@ static int control(vf_instance_t *vf, int request, void *data)
vf->priv->osd = data;
break;
case VFCTRL_INIT_EOSD:
- vf->priv->renderer_realaspect = ass_renderer_init((ASS_Library *)data);
- if (!vf->priv->renderer_realaspect)
+ vf->priv->renderer = ass_renderer_init((ASS_Library *)data);
+ if (!vf->priv->renderer)
return CONTROL_FALSE;
- vf->priv->renderer_vsfilter = ass_renderer_init((ASS_Library *)data);
- if (!vf->priv->renderer_vsfilter) {
- ass_renderer_done(vf->priv->renderer_realaspect);
- return CONTROL_FALSE;
- }
- mp_ass_configure_fonts(vf->priv->renderer_realaspect);
- mp_ass_configure_fonts(vf->priv->renderer_vsfilter);
+ mp_ass_configure_fonts(vf->priv->renderer);
return CONTROL_TRUE;
case VFCTRL_DRAW_EOSD:
- if (vf->priv->renderer_realaspect)
+ if (vf->priv->renderer)
return CONTROL_TRUE;
break;
}
@@ -423,10 +413,8 @@ static int control(vf_instance_t *vf, int request, void *data)
static void uninit(struct vf_instance *vf)
{
- if (vf->priv->renderer_realaspect) {
- ass_renderer_done(vf->priv->renderer_realaspect);
- ass_renderer_done(vf->priv->renderer_vsfilter);
- }
+ if (vf->priv->renderer)
+ ass_renderer_done(vf->priv->renderer);
free(vf->priv->planes[1]);
free(vf->priv->planes[2]);
free(vf->priv->line_limits);
diff --git a/libmpcodecs/vf_gradfun.c b/libmpcodecs/vf_gradfun.c
index 813b9ecb3f..c74fbfe5fb 100644
--- a/libmpcodecs/vf_gradfun.c
+++ b/libmpcodecs/vf_gradfun.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
+#include <math.h>
#include "config.h"
#include "cpudetect.h"
@@ -41,7 +42,13 @@
#include "libavutil/avutil.h"
#include "ffmpeg_files/x86_cpu.h"
+#include "m_option.h"
+#include "m_struct.h"
+
struct vf_priv_s {
+ float cfg_thresh;
+ int cfg_radius;
+ float cfg_size;
int thresh;
int radius;
uint16_t *buf;
@@ -49,6 +56,10 @@ struct vf_priv_s {
int width, int thresh, const uint16_t *dithers);
void (*blur_line)(uint16_t *dc, uint16_t *buf, uint16_t *buf1,
uint8_t *src, int sstride, int width);
+} const vf_priv_dflt = {
+ .cfg_thresh = 1.5,
+ .cfg_radius = -1,
+ .cfg_size = -1,
};
static const uint16_t __attribute__((aligned(16))) pw_7f[8] = {127,127,127,127,127,127,127,127};
@@ -354,6 +365,12 @@ static int config(struct vf_instance *vf,
unsigned int flags, unsigned int outfmt)
{
free(vf->priv->buf);
+ vf->priv->radius = vf->priv->cfg_radius;
+ if (vf->priv->cfg_size > -1) {
+ vf->priv->radius = (vf->priv->cfg_size / 100.0f)
+ * sqrtf(width * width + height * height);
+ }
+ vf->priv->radius = av_clip((vf->priv->radius+1)&~1, 4, 32);
vf->priv->buf = av_mallocz((((width+15)&~15)*(vf->priv->radius+1)/2+32)*sizeof(uint16_t));
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
}
@@ -368,20 +385,25 @@ static void uninit(struct vf_instance *vf)
static int vf_open(vf_instance_t *vf, char *args)
{
- float thresh = 1.2;
- int radius = 16;
-
vf->get_image=get_image;
vf->put_image=put_image;
vf->query_format=query_format;
vf->config=config;
vf->uninit=uninit;
- vf->priv=malloc(sizeof(struct vf_priv_s));
- memset(vf->priv, 0, sizeof(struct vf_priv_s));
- if (args) sscanf(args, "%f:%d", &thresh, &radius);
- vf->priv->thresh = (1<<15)/av_clipf(thresh,0.51,255);
- vf->priv->radius = av_clip((radius+1)&~1,4,32);
+ bool have_radius = vf->priv->cfg_radius > -1;
+ bool have_size = vf->priv->cfg_size > -1;
+
+ if (have_radius && have_size) {
+ mp_msg(MSGT_VFILTER, MSGL_ERR, "scale: gradfun: only one of "
+ "radius/size parameters allowed at the same time!\n");
+ return 0;
+ }
+
+ if (!have_radius && !have_size)
+ vf->priv->cfg_size = 1.0;
+
+ vf->priv->thresh = (1<<15)/av_clipf(vf->priv->cfg_thresh,0.51,255);
vf->priv->blur_line = blur_line_c;
vf->priv->filter_line = filter_line_c;
@@ -401,11 +423,27 @@ static int vf_open(vf_instance_t *vf, char *args)
return 1;
}
+#undef ST_OFF
+#define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f)
+static const m_option_t vf_opts_fields[] = {
+ {"strength", ST_OFF(cfg_thresh), CONF_TYPE_FLOAT, M_OPT_RANGE, 0.51, 255, NULL},
+ {"radius", ST_OFF(cfg_radius), CONF_TYPE_INT, M_OPT_RANGE, 4, 32, NULL},
+ {"size", ST_OFF(cfg_size), CONF_TYPE_FLOAT, M_OPT_RANGE, 0.1, 5.0, NULL},
+ { NULL, NULL, 0, 0, 0, 0, NULL }
+};
+
+static const m_struct_t vf_opts = {
+ "gradfun",
+ sizeof(struct vf_priv_s),
+ &vf_priv_dflt,
+ vf_opts_fields
+};
+
const vf_info_t vf_info_gradfun = {
"gradient deband",
"gradfun",
"Loren Merritt",
"",
vf_open,
- NULL
+ &vf_opts
};
diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c
index 585ef4d9a1..4ccef63054 100644
--- a/libmpcodecs/vf_scale.c
+++ b/libmpcodecs/vf_scale.c
@@ -107,6 +107,7 @@ static const unsigned int outfmt_list[]={
IMGFMT_RGB32,
IMGFMT_BGR24,
IMGFMT_RGB24,
+ IMGFMT_GBRP,
IMGFMT_RGB48LE,
IMGFMT_RGB48BE,
IMGFMT_BGR16,
@@ -141,6 +142,10 @@ static int preferred_conversions[][2] = {
{IMGFMT_UYVY, IMGFMT_422P},
{IMGFMT_422P, IMGFMT_YUY2},
{IMGFMT_422P, IMGFMT_UYVY},
+ {IMGFMT_GBRP, IMGFMT_BGR24},
+ {IMGFMT_GBRP, IMGFMT_RGB24},
+ {IMGFMT_GBRP, IMGFMT_BGR32},
+ {IMGFMT_GBRP, IMGFMT_RGB32},
{0, 0}
};
@@ -704,7 +709,7 @@ void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, Sw
}
// will use sws_flags & src_filter (from cmd line)
-struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat)
+static struct SwsContext *sws_getContextFromCmdLine2(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int extraflags)
{
int flags;
SwsFilter *dstFilterParam, *srcFilterParam;
@@ -715,7 +720,18 @@ struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int 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 | get_sws_cpuflags(), srcFilterParam, dstFilterParam, NULL);
+ return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags | extraflags | get_sws_cpuflags(), 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
diff --git a/libmpcodecs/vf_scale.h b/libmpcodecs/vf_scale.h
index a9b3b506d5..08d651ce16 100644
--- a/libmpcodecs/vf_scale.h
+++ b/libmpcodecs/vf_scale.h
@@ -21,6 +21,7 @@
int get_sws_cpuflags(void);
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);
diff --git a/libmpcodecs/vf_screenshot.c b/libmpcodecs/vf_screenshot.c
index 7f9a45c879..eb961d8118 100644
--- a/libmpcodecs/vf_screenshot.c
+++ b/libmpcodecs/vf_screenshot.c
@@ -197,7 +197,6 @@ static int vf_open(vf_instance_t *vf, char *args)
return 1;
}
-
const vf_info_t vf_info_screenshot = {
"screenshot to file",
"screenshot",
@@ -207,4 +206,15 @@ const vf_info_t vf_info_screenshot = {
NULL
};
+// screenshot.c will look for a filter named "screenshot_force", and not use
+// the VO based screenshot code if it's in the filter chain.
+const vf_info_t vf_info_screenshot_force = {
+ "screenshot to file (override VO based screenshot code)",
+ "screenshot_force",
+ "A'rpi, Jindrich Makovicka",
+ "",
+ vf_open,
+ NULL
+};
+
//===========================================================================//
diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
index 0f89d7312f..a6bd165dee 100644
--- a/libmpcodecs/vf_vo.c
+++ b/libmpcodecs/vf_vo.c
@@ -38,8 +38,7 @@ extern float sub_delay;
struct vf_priv_s {
struct vo *vo;
#ifdef CONFIG_ASS
- ASS_Renderer *renderer_realaspect;
- ASS_Renderer *renderer_vsfilter;
+ ASS_Renderer *renderer;
bool prev_visibility;
double scale_ratio;
#endif
@@ -85,10 +84,8 @@ static int config(struct vf_instance *vf,
#ifdef CONFIG_ASS
vf->priv->scale_ratio = (double) d_width / d_height * height / width;
- if (vf->priv->renderer_realaspect) {
- mp_ass_configure(vf->priv->renderer_realaspect, vf->opts, width, height,
- vf->default_caps & VFCAP_EOSD_UNSCALED);
- mp_ass_configure(vf->priv->renderer_vsfilter, vf->opts, width, height,
+ if (vf->priv->renderer) {
+ mp_ass_configure(vf->priv->renderer, vf->opts, width, height,
vf->default_caps & VFCAP_EOSD_UNSCALED);
}
@@ -138,30 +135,23 @@ static int control(struct vf_instance *vf, int request, void *data)
return vo_control(video_out, VOCTRL_GET_EQUALIZER, &param) == VO_TRUE;
}
#ifdef CONFIG_ASS
- case VFCTRL_INIT_EOSD: {
- vf->priv->renderer_realaspect = ass_renderer_init(data);
- if (!vf->priv->renderer_realaspect)
- return CONTROL_FALSE;
- vf->priv->renderer_vsfilter = ass_renderer_init(data);
- if (!vf->priv->renderer_vsfilter) {
- ass_renderer_done(vf->priv->renderer_realaspect);
+ case VFCTRL_INIT_EOSD:
+ {
+ vf->priv->renderer = ass_renderer_init(data);
+ if (!vf->priv->renderer)
return CONTROL_FALSE;
- }
- mp_ass_configure_fonts(vf->priv->renderer_realaspect);
- mp_ass_configure_fonts(vf->priv->renderer_vsfilter);
+ mp_ass_configure_fonts(vf->priv->renderer);
vf->priv->prev_visibility = false;
return CONTROL_TRUE;
}
case VFCTRL_DRAW_EOSD: {
struct osd_state *osd = data;
- mp_eosd_images_t images = { NULL, 2 };
- ASS_Renderer *renderer;
+ mp_eosd_images_t images = {NULL, 2};
+ ASS_Renderer *renderer = vf->priv->renderer;
double scale;
if (osd->vsfilter_aspect && vf->opts->ass_vsfilter_aspect_compat) {
- renderer = vf->priv->renderer_vsfilter;
scale = vf->priv->scale_ratio;
} else {
- renderer = vf->priv->renderer_realaspect;
scale = 1;
}
if (!video_out->config_ok || !renderer)
@@ -177,10 +167,8 @@ static int control(struct vf_instance *vf, int request, void *data)
ass_set_aspect_ratio(renderer, scale, 1);
}
- if (osd->ass_force_reload) {
- mp_ass_reload_options(vf->priv->renderer_realaspect, vf->opts);
- mp_ass_reload_options(vf->priv->renderer_vsfilter, vf->opts);
- }
+ if (osd->ass_force_reload)
+ mp_ass_reload_options(vf->priv->renderer, vf->opts);
images.imgs = ass_render_frame(renderer, osd->ass_track,
(osd->pts + sub_delay) * 1000 + .5,
&images.changed);
@@ -229,7 +217,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
// blit frame:
if (vf->default_caps & VFCAP_ACCEPT_STRIDE)
vo_draw_slice(video_out, mpi->planes, mpi->stride, mpi->w, mpi->h,
- mpi->x, mpi->y);
+ 0, 0);
else
vo_draw_frame(video_out, mpi->planes);
}
@@ -258,10 +246,8 @@ static void uninit(struct vf_instance *vf)
* to get rid of numbered-mpi references that will now be invalid. */
vo_seek_reset(video_out);
#ifdef CONFIG_ASS
- if (vf->priv->renderer_realaspect) {
- ass_renderer_done(vf->priv->renderer_realaspect);
- ass_renderer_done(vf->priv->renderer_vsfilter);
- }
+ if (vf->priv->renderer)
+ ass_renderer_done(vf->priv->renderer);
#endif
free(vf->priv);
}