diff options
Diffstat (limited to 'libmpcodecs')
-rw-r--r-- | libmpcodecs/img_format.c | 1 | ||||
-rw-r--r-- | libmpcodecs/img_format.h | 2 | ||||
-rw-r--r-- | libmpcodecs/mp_image.c | 7 | ||||
-rw-r--r-- | libmpcodecs/mp_image.h | 2 | ||||
-rw-r--r-- | libmpcodecs/vd.c | 6 | ||||
-rw-r--r-- | libmpcodecs/vf.c | 2 | ||||
-rw-r--r-- | libmpcodecs/vf_ass.c | 50 | ||||
-rw-r--r-- | libmpcodecs/vf_gradfun.c | 56 | ||||
-rw-r--r-- | libmpcodecs/vf_scale.c | 20 | ||||
-rw-r--r-- | libmpcodecs/vf_scale.h | 1 | ||||
-rw-r--r-- | libmpcodecs/vf_screenshot.c | 12 | ||||
-rw-r--r-- | libmpcodecs/vf_vo.c | 44 |
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, ¶m) == 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); } |