mirror of
https://github.com/mpv-player/mpv.git
synced 2025-12-28 05:33:14 +00:00
video: remove slice based filtering and video output
Slices allowed filtering or drawing video in horizontal bands or blocks. This allowed working on the video in smaller units. In theory, this could bring a performance win by lowering cache pressure, as you didn't have to keep the whole video frame in cache while filtering, only the slice. In practice, the slice code path was barely used for the following reasons: - Multithreaded decoding with ffmpeg didn't use slices. The ffmpeg slice callback was disabled, because it can be called from another thread, and the mplayer video chain is not thread-safe. - There was nothing that would turn "full" images into appropriate slices, so slices were rarely used. - Most filters didn't actually support slices. On the other hand, supporting slices lead to code duplication and more complex code in general. I made some experiments and didn't find any actual measurable performance improvements when using slices. Even ffmpeg removed slices based filtering from libavfilter in favor of simpler code. The most broken thing about the slices code path is that slices can't be queued, like it is done for images in vo.c.
This commit is contained in:
@@ -937,7 +937,7 @@
|
||||
:8: macroblock (MB) type
|
||||
:16: per-block quantization parameter (QP)
|
||||
:32: motion vector
|
||||
:0x0040: motion vector visualization (use ``--no-slices``)
|
||||
:0x0040: motion vector visualization
|
||||
:0x0080: macroblock (MB) skip
|
||||
:0x0100: startcode
|
||||
:0x0200: PTS
|
||||
@@ -1759,12 +1759,6 @@
|
||||
|
||||
This affects smplayer, smplayer2, mplayerosx, and others.
|
||||
|
||||
--slices, --no-slices
|
||||
Drawing video by 16-pixel height slices/bands, instead draws the
|
||||
whole frame in a single run. May be faster or slower, depending on video
|
||||
card and available cache. It has effect only with libavcodec codecs.
|
||||
Enabled by default if applicable; usually disabled when threading is used.
|
||||
|
||||
--softsleep
|
||||
Time frames by repeatedly checking the current time instead of asking
|
||||
the kernel to wake up mpv at the correct time. Useful if your kernel
|
||||
|
||||
@@ -482,8 +482,6 @@ const m_option_t common_opts[] = {
|
||||
|
||||
OPT_FLAG_CONSTANTS("flip", flip, 0, -1, 1),
|
||||
|
||||
// draw by slices or whole frame (useful with libmpeg2/libavcodec)
|
||||
OPT_MAKE_FLAGS("slices", vd_use_slices, 0),
|
||||
// use (probably completely broken) decoder direct rendering
|
||||
OPT_MAKE_FLAGS("dr1", vd_use_dr1, 0),
|
||||
{"field-dominance", &field_dominance, CONF_TYPE_CHOICE, 0,
|
||||
|
||||
@@ -108,7 +108,6 @@ typedef struct MPOpts {
|
||||
float movie_aspect;
|
||||
float screen_size_xy;
|
||||
int flip;
|
||||
int vd_use_slices;
|
||||
int vd_use_dr1;
|
||||
char **sub_name;
|
||||
char **sub_paths;
|
||||
|
||||
@@ -261,12 +261,3 @@ mp_image_t *mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag,
|
||||
{
|
||||
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,
|
||||
int w, int h, int x, int y)
|
||||
{
|
||||
struct vf_instance *vf = sh->vfilter;
|
||||
|
||||
if (vf->draw_slice)
|
||||
vf->draw_slice(vf, src, stride, w, h, x, y);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,5 @@ int mpcodecs_config_vo(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);
|
||||
void mpcodecs_draw_slice(sh_video_t *sh, unsigned char **src, int *stride,
|
||||
int w, int h, int x, int y);
|
||||
|
||||
#endif /* MPLAYER_VD_H */
|
||||
|
||||
@@ -66,7 +66,6 @@ typedef struct {
|
||||
AVCodecContext *avctx;
|
||||
AVFrame *pic;
|
||||
enum PixelFormat pix_fmt;
|
||||
int do_slices;
|
||||
int do_dr1;
|
||||
int vo_initialized;
|
||||
int best_csp;
|
||||
@@ -83,8 +82,6 @@ typedef struct {
|
||||
|
||||
static int get_buffer(AVCodecContext *avctx, AVFrame *pic);
|
||||
static void release_buffer(AVCodecContext *avctx, AVFrame *pic);
|
||||
static void draw_slice(struct AVCodecContext *s, const AVFrame *src,
|
||||
int offset[4], int y, int type, int height);
|
||||
static void draw_slice_hwdec(struct AVCodecContext *s, const AVFrame *src,
|
||||
int offset[4], int y, int type, int height);
|
||||
|
||||
@@ -169,11 +166,6 @@ static int init(sh_video_t *sh)
|
||||
if (!sh->codecname)
|
||||
sh->codecname = lavc_codec->name;
|
||||
|
||||
if (sh->opts->vd_use_slices
|
||||
&& (lavc_codec->capabilities & CODEC_CAP_DRAW_HORIZ_BAND)
|
||||
&& !do_vis_debug)
|
||||
ctx->do_slices = 1;
|
||||
|
||||
if (lavc_codec->capabilities & CODEC_CAP_DR1 && !do_vis_debug
|
||||
&& lavc_codec->id != CODEC_ID_H264
|
||||
&& lavc_codec->id != CODEC_ID_INTERPLAY_VIDEO
|
||||
@@ -192,7 +184,6 @@ static int init(sh_video_t *sh)
|
||||
if (lavc_codec->capabilities & CODEC_CAP_HWACCEL // XvMC
|
||||
|| lavc_codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
|
||||
ctx->do_dr1 = true;
|
||||
ctx->do_slices = true;
|
||||
lavc_param->threads = 1;
|
||||
avctx->get_format = get_format;
|
||||
avctx->get_buffer = get_buffer;
|
||||
@@ -219,7 +210,6 @@ static int init(sh_video_t *sh)
|
||||
* from other threads. */
|
||||
if (lavc_param->threads > 1) {
|
||||
ctx->do_dr1 = false;
|
||||
ctx->do_slices = false;
|
||||
mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Asking decoder to use "
|
||||
"%d threads if supported.\n", lavc_param->threads);
|
||||
}
|
||||
@@ -384,34 +374,6 @@ static void draw_slice_hwdec(struct AVCodecContext *s,
|
||||
vf->control(vf, VFCTRL_HWDEC_DECODER_RENDER, state_ptr);
|
||||
}
|
||||
|
||||
static void draw_slice(struct AVCodecContext *s,
|
||||
const AVFrame *src, int offset[4],
|
||||
int y, int type, int height)
|
||||
{
|
||||
sh_video_t *sh = s->opaque;
|
||||
uint8_t *source[MP_MAX_PLANES] = {
|
||||
src->data[0] + offset[0], src->data[1] + offset[1],
|
||||
src->data[2] + offset[2]
|
||||
};
|
||||
int strides[MP_MAX_PLANES] = {
|
||||
src->linesize[0], src->linesize[1], src->linesize[2]
|
||||
};
|
||||
if (height < 0) {
|
||||
int i;
|
||||
height = -height;
|
||||
y -= height;
|
||||
for (i = 0; i < MP_MAX_PLANES; i++) {
|
||||
strides[i] = -strides[i];
|
||||
source[i] -= strides[i];
|
||||
}
|
||||
}
|
||||
if (y < sh->disp_h) {
|
||||
height = FFMIN(height, sh->disp_h - y);
|
||||
mpcodecs_draw_slice(sh, source, strides, sh->disp_w, height, 0, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int init_vo(sh_video_t *sh, enum PixelFormat pix_fmt)
|
||||
{
|
||||
vd_ffmpeg_ctx *ctx = sh->context;
|
||||
@@ -498,17 +460,14 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic)
|
||||
type = MP_IMGTYPE_STATIC;
|
||||
flags |= MP_IMGFLAG_PRESERVE;
|
||||
}
|
||||
flags |= ctx->do_slices ? MP_IMGFLAG_DRAW_CALLBACK : 0;
|
||||
mp_msg(MSGT_DECVIDEO, MSGL_DBG2,
|
||||
type == MP_IMGTYPE_STATIC ? "using STATIC\n" : "using TEMP\n");
|
||||
} else {
|
||||
if (!pic->reference) {
|
||||
ctx->b_count++;
|
||||
flags |= ctx->do_slices ? MP_IMGFLAG_DRAW_CALLBACK : 0;
|
||||
} else {
|
||||
ctx->ip_count++;
|
||||
flags |= MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE
|
||||
| (ctx->do_slices ? MP_IMGFLAG_DRAW_CALLBACK : 0);
|
||||
flags |= MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,16 +508,6 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic)
|
||||
if (!mpi)
|
||||
return -1;
|
||||
|
||||
// ok, let's see what did we get:
|
||||
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK &&
|
||||
!(mpi->flags & MP_IMGFLAG_DIRECT)) {
|
||||
// nice, filter/vo likes draw_callback :)
|
||||
avctx->draw_horiz_band = draw_slice;
|
||||
} else
|
||||
avctx->draw_horiz_band = NULL;
|
||||
if (IMGFMT_IS_HWACCEL(mpi->imgfmt))
|
||||
avctx->draw_horiz_band = draw_slice_hwdec;
|
||||
|
||||
pic->data[0] = mpi->planes[0];
|
||||
pic->data[1] = mpi->planes[1];
|
||||
pic->data[2] = mpi->planes[2];
|
||||
|
||||
@@ -260,11 +260,9 @@ mp_image_t *vf_get_image(vf_instance_t *vf, unsigned int outfmt,
|
||||
// keep buffer allocation status & color flags only:
|
||||
mpi->flags &= MP_IMGFLAG_ALLOCATED | MP_IMGFLAG_TYPE_DISPLAYED |
|
||||
MP_IMGFLAGMASK_COLORS;
|
||||
// accept restrictions, draw_slice and palette flags only:
|
||||
// accept restrictions, palette flags only:
|
||||
mpi->flags |= mp_imgflag & (MP_IMGFLAGMASK_RESTRICTIONS |
|
||||
MP_IMGFLAG_DRAW_CALLBACK | MP_IMGFLAG_RGB_PALETTE);
|
||||
if (!vf->draw_slice)
|
||||
mpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK;
|
||||
MP_IMGFLAG_RGB_PALETTE);
|
||||
if (mpi->width != w2 || mpi->height != h || missing_palette) {
|
||||
if (mpi->flags & MP_IMGFLAG_ALLOCATED) {
|
||||
if (mpi->width < w2 || mpi->height < h || missing_palette) {
|
||||
@@ -331,17 +329,13 @@ mp_image_t *vf_get_image(vf_instance_t *vf, unsigned int outfmt,
|
||||
vf_mpi_clear(mpi, 0, 0, mpi->width, mpi->height);
|
||||
}
|
||||
}
|
||||
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
|
||||
if (vf->start_slice)
|
||||
vf->start_slice(vf, mpi);
|
||||
if (!(mpi->flags & MP_IMGFLAG_TYPE_DISPLAYED)) {
|
||||
mp_msg(MSGT_DECVIDEO, MSGL_V,
|
||||
"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
|
||||
"*** [%s] %s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
|
||||
vf->info->name,
|
||||
(mpi->type == MP_IMGTYPE_EXPORT) ? "Exporting" :
|
||||
((mpi->flags & MP_IMGFLAG_DIRECT) ?
|
||||
"Direct Rendering" : "Allocating"),
|
||||
(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) ? " (slices)" : "",
|
||||
mpi->width, mpi->height, mpi->bpp,
|
||||
(mpi->flags & MP_IMGFLAG_YUV) ? "YUV" :
|
||||
((mpi->flags & MP_IMGFLAG_SWAPPED) ? "BGR" : "RGB"),
|
||||
@@ -664,39 +658,6 @@ int vf_next_put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
|
||||
return vf->next->put_image(vf->next, mpi, pts);
|
||||
}
|
||||
|
||||
void vf_next_draw_slice(struct vf_instance *vf, unsigned char **src,
|
||||
int *stride, int w, int h, int x, int y)
|
||||
{
|
||||
if (vf->next->draw_slice) {
|
||||
vf->next->draw_slice(vf->next, src, stride, w, h, x, y);
|
||||
return;
|
||||
}
|
||||
if (!vf->dmpi) {
|
||||
mp_msg(MSGT_VFILTER, MSGL_ERR,
|
||||
"draw_slice: dmpi not stored by vf_%s\n", vf->info->name);
|
||||
return;
|
||||
}
|
||||
if (!(vf->dmpi->flags & MP_IMGFLAG_PLANAR)) {
|
||||
memcpy_pic(vf->dmpi->planes[0] + y * vf->dmpi->stride[0] +
|
||||
vf->dmpi->bpp / 8 * x,
|
||||
src[0], vf->dmpi->bpp / 8 * w, h, vf->dmpi->stride[0],
|
||||
stride[0]);
|
||||
return;
|
||||
}
|
||||
memcpy_pic(vf->dmpi->planes[0] + y * vf->dmpi->stride[0] + x, src[0],
|
||||
w, h, vf->dmpi->stride[0], stride[0]);
|
||||
memcpy_pic(vf->dmpi->planes[1]
|
||||
+ (y >> vf->dmpi->chroma_y_shift) * vf->dmpi->stride[1]
|
||||
+ (x >> vf->dmpi->chroma_x_shift),
|
||||
src[1], w >> vf->dmpi->chroma_x_shift,
|
||||
h >> vf->dmpi->chroma_y_shift, vf->dmpi->stride[1], stride[1]);
|
||||
memcpy_pic(vf->dmpi->planes[2]
|
||||
+ (y >> vf->dmpi->chroma_y_shift) * vf->dmpi->stride[2]
|
||||
+ (x >> vf->dmpi->chroma_x_shift),
|
||||
src[2], w >> vf->dmpi->chroma_x_shift,
|
||||
h >> vf->dmpi->chroma_y_shift, vf->dmpi->stride[2], stride[2]);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
vf_instance_t *append_filters(vf_instance_t *last,
|
||||
|
||||
@@ -66,9 +66,6 @@ typedef struct vf_instance {
|
||||
int (*query_format)(struct vf_instance *vf, unsigned int fmt);
|
||||
void (*get_image)(struct vf_instance *vf, mp_image_t *mpi);
|
||||
int (*put_image)(struct vf_instance *vf, mp_image_t *mpi, double pts);
|
||||
void (*start_slice)(struct vf_instance *vf, mp_image_t *mpi);
|
||||
void (*draw_slice)(struct vf_instance *vf, unsigned char **src,
|
||||
int *stride, int w, int h, int x, int y);
|
||||
void (*uninit)(struct vf_instance *vf);
|
||||
|
||||
int (*continue_buffered_image)(struct vf_instance *vf);
|
||||
@@ -141,8 +138,6 @@ int vf_next_config(struct vf_instance *vf,
|
||||
int vf_next_control(struct vf_instance *vf, int request, void *data);
|
||||
int vf_next_query_format(struct vf_instance *vf, unsigned int fmt);
|
||||
int vf_next_put_image(struct vf_instance *vf, mp_image_t *mpi, double pts);
|
||||
void vf_next_draw_slice(struct vf_instance *vf, unsigned char **src,
|
||||
int *stride, int w, int h, int x, int y);
|
||||
|
||||
struct m_obj_settings;
|
||||
vf_instance_t *append_filters(vf_instance_t *last,
|
||||
|
||||
@@ -86,8 +86,6 @@ static int config(struct vf_instance *vf,
|
||||
|
||||
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
|
||||
mp_image_t *dmpi;
|
||||
if (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
|
||||
return vf_next_put_image(vf,vf->dmpi, pts);
|
||||
dmpi=vf_get_image(vf->next,mpi->imgfmt,
|
||||
MP_IMGTYPE_EXPORT, 0,
|
||||
vf->priv->crop_w, vf->priv->crop_h);
|
||||
@@ -111,54 +109,11 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
|
||||
return vf_next_put_image(vf,dmpi, pts);
|
||||
}
|
||||
|
||||
static void start_slice(struct vf_instance *vf, mp_image_t *mpi){
|
||||
vf->dmpi = vf_get_image(vf->next, mpi->imgfmt, mpi->type, mpi->flags,
|
||||
vf->priv->crop_w, vf->priv->crop_h);
|
||||
}
|
||||
|
||||
static void draw_slice(struct vf_instance *vf,
|
||||
unsigned char** src, int* stride, int w,int h, int x, int y){
|
||||
unsigned char *src2[3];
|
||||
src2[0] = src[0];
|
||||
if (vf->dmpi->flags & MP_IMGFLAG_PLANAR) {
|
||||
src2[1] = src[1];
|
||||
src2[2] = src[2];
|
||||
}
|
||||
//mp_msg(MSGT_VFILTER, MSGL_V, "crop slice %d %d %d %d ->", w,h,x,y);
|
||||
if ((x -= vf->priv->crop_x) < 0) {
|
||||
x = -x;
|
||||
src2[0] += x;
|
||||
if (vf->dmpi->flags & MP_IMGFLAG_PLANAR) {
|
||||
src2[1] += x>>vf->dmpi->chroma_x_shift;
|
||||
src2[2] += x>>vf->dmpi->chroma_x_shift;
|
||||
}
|
||||
w -= x;
|
||||
x = 0;
|
||||
}
|
||||
if ((y -= vf->priv->crop_y) < 0) {
|
||||
y = -y;
|
||||
src2[0] += y*stride[0];
|
||||
if (vf->dmpi->flags & MP_IMGFLAG_PLANAR) {
|
||||
src2[1] += (y>>vf->dmpi->chroma_y_shift)*stride[1];
|
||||
src2[2] += (y>>vf->dmpi->chroma_y_shift)*stride[2];
|
||||
}
|
||||
h -= y;
|
||||
y = 0;
|
||||
}
|
||||
if (x+w > vf->priv->crop_w) w = vf->priv->crop_w-x;
|
||||
if (y+h > vf->priv->crop_h) h = vf->priv->crop_h-y;
|
||||
//mp_msg(MSGT_VFILTER, MSGL_V, "%d %d %d %d\n", w,h,x,y);
|
||||
if (w <= 0 || h <= 0) return;
|
||||
vf_next_draw_slice(vf,src2,stride,w,h,x,y);
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char *args){
|
||||
vf->config=config;
|
||||
vf->put_image=put_image;
|
||||
vf->start_slice=start_slice;
|
||||
vf->draw_slice=draw_slice;
|
||||
vf->default_reqs=VFCAP_ACCEPT_STRIDE;
|
||||
mp_msg(MSGT_VFILTER, MSGL_INFO, "Crop: %d x %d, %d ; %d\n",
|
||||
vf->priv->crop_w,
|
||||
|
||||
@@ -84,7 +84,6 @@ static void uninit(vf_instance_t *vf) {
|
||||
static int vf_open(vf_instance_t *vf, char *args)
|
||||
{
|
||||
vf->config = config;
|
||||
vf->draw_slice = vf_next_draw_slice;
|
||||
vf->uninit = uninit;
|
||||
//vf->default_caps = 0;
|
||||
vf->priv = calloc(sizeof(struct vf_priv_s), 1);
|
||||
|
||||
@@ -48,7 +48,6 @@ static struct vf_priv_s {
|
||||
int exp_x,exp_y;
|
||||
double aspect;
|
||||
int round;
|
||||
int first_slice;
|
||||
} const vf_priv_dflt = {
|
||||
-1,-1,
|
||||
-1,-1,
|
||||
@@ -56,7 +55,6 @@ static struct vf_priv_s {
|
||||
-1,-1,
|
||||
0.,
|
||||
1,
|
||||
0
|
||||
};
|
||||
|
||||
//===========================================================================//
|
||||
@@ -141,11 +139,6 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
|
||||
mpi->type, mpi->flags,
|
||||
FFMAX(vf->priv->exp_w, mpi->width +vf->priv->exp_x),
|
||||
FFMAX(vf->priv->exp_h, mpi->height+vf->priv->exp_y));
|
||||
if((vf->dmpi->flags & MP_IMGFLAG_DRAW_CALLBACK) &&
|
||||
!(vf->dmpi->flags & MP_IMGFLAG_DIRECT)){
|
||||
mp_tmsg(MSGT_VFILTER, MSGL_INFO, "Full DR not possible, trying SLICES instead!\n");
|
||||
return;
|
||||
}
|
||||
// set up mpi as a cropped-down image of dmpi:
|
||||
if(mpi->flags&MP_IMGFLAG_PLANAR){
|
||||
mpi->planes[0]=vf->dmpi->planes[0]+
|
||||
@@ -164,75 +157,9 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi){
|
||||
mpi->stride[0]=vf->dmpi->stride[0];
|
||||
mpi->width=vf->dmpi->width;
|
||||
mpi->flags|=MP_IMGFLAG_DIRECT;
|
||||
mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
|
||||
// vf->dmpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
|
||||
}
|
||||
}
|
||||
|
||||
static void start_slice(struct vf_instance *vf, mp_image_t *mpi){
|
||||
// printf("start_slice called! flag=%d\n",mpi->flags&MP_IMGFLAG_DRAW_CALLBACK);
|
||||
// they want slices!!! allocate the buffer.
|
||||
if(!mpi->priv)
|
||||
mpi->priv=vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
|
||||
// MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
|
||||
MP_IMGTYPE_TEMP, mpi->flags,
|
||||
FFMAX(vf->priv->exp_w, mpi->width +vf->priv->exp_x),
|
||||
FFMAX(vf->priv->exp_h, mpi->height+vf->priv->exp_y));
|
||||
vf->priv->first_slice = 1;
|
||||
}
|
||||
|
||||
static void draw_top_blackbar_slice(struct vf_instance *vf,
|
||||
unsigned char** src, int* stride, int w,int h, int x, int y){
|
||||
if(vf->priv->exp_y>0 && y == 0) {
|
||||
vf_next_draw_slice(vf, vf->dmpi->planes, vf->dmpi->stride,
|
||||
vf->dmpi->w,vf->priv->exp_y,0,0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void draw_bottom_blackbar_slice(struct vf_instance *vf,
|
||||
unsigned char** src, int* stride, int w,int h, int x, int y){
|
||||
if(vf->priv->exp_y+vf->h<vf->dmpi->h && y+h == vf->h) {
|
||||
unsigned char *src2[MP_MAX_PLANES];
|
||||
src2[0] = vf->dmpi->planes[0]
|
||||
+ (vf->priv->exp_y+vf->h)*vf->dmpi->stride[0];
|
||||
if(vf->dmpi->flags&MP_IMGFLAG_PLANAR){
|
||||
src2[1] = vf->dmpi->planes[1]
|
||||
+ ((vf->priv->exp_y+vf->h)>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[1];
|
||||
src2[2] = vf->dmpi->planes[2]
|
||||
+ ((vf->priv->exp_y+vf->h)>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[2];
|
||||
} else {
|
||||
src2[1] = vf->dmpi->planes[1]; // passthrough rgb8 palette
|
||||
}
|
||||
vf_next_draw_slice(vf, src2, vf->dmpi->stride,
|
||||
vf->dmpi->w,vf->dmpi->h-(vf->priv->exp_y+vf->h),
|
||||
0,vf->priv->exp_y+vf->h);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_slice(struct vf_instance *vf,
|
||||
unsigned char** src, int* stride, int w,int h, int x, int y){
|
||||
// printf("draw_slice() called %d at %d\n",h,y);
|
||||
|
||||
if (y == 0 && y+h == vf->h) {
|
||||
// special case - only one slice
|
||||
draw_top_blackbar_slice(vf, src, stride, w, h, x, y);
|
||||
vf_next_draw_slice(vf,src,stride,w,h,x+vf->priv->exp_x,y+vf->priv->exp_y);
|
||||
draw_bottom_blackbar_slice(vf, src, stride, w, h, x, y);
|
||||
return;
|
||||
}
|
||||
if (vf->priv->first_slice) {
|
||||
draw_top_blackbar_slice(vf, src, stride, w, h, x, y);
|
||||
draw_bottom_blackbar_slice(vf, src, stride, w, h, x, y);
|
||||
}
|
||||
vf_next_draw_slice(vf,src,stride,w,h,x+vf->priv->exp_x,y+vf->priv->exp_y);
|
||||
if (!vf->priv->first_slice) {
|
||||
draw_top_blackbar_slice(vf, src, stride, w, h, x, y);
|
||||
draw_bottom_blackbar_slice(vf, src, stride, w, h, x, y);
|
||||
}
|
||||
vf->priv->first_slice = 0;
|
||||
}
|
||||
|
||||
// w, h = width and height of the actual video frame (located at exp_x/exp_y)
|
||||
static void clear_borders(struct vf_instance *vf, int w, int h)
|
||||
{
|
||||
@@ -249,7 +176,7 @@ static void clear_borders(struct vf_instance *vf, int w, int h)
|
||||
}
|
||||
|
||||
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
|
||||
if(mpi->flags&MP_IMGFLAG_DIRECT || mpi->flags&MP_IMGFLAG_DRAW_CALLBACK){
|
||||
if(mpi->flags&MP_IMGFLAG_DIRECT){
|
||||
vf->dmpi=mpi->priv;
|
||||
if(!vf->dmpi) { mp_tmsg(MSGT_VFILTER, MSGL_WARN, "Why do we get NULL??\n"); return 0; }
|
||||
mpi->priv=NULL;
|
||||
@@ -304,8 +231,6 @@ static int vf_open(vf_instance_t *vf, char *args){
|
||||
vf->config=config;
|
||||
vf->control=control;
|
||||
vf->query_format=query_format;
|
||||
vf->start_slice=start_slice;
|
||||
vf->draw_slice=draw_slice;
|
||||
vf->get_image=get_image;
|
||||
vf->put_image=put_image;
|
||||
mp_msg(MSGT_VFILTER, MSGL_INFO, "Expand: %d x %d, %d ; %d, aspect: %f, round: %d\n",
|
||||
|
||||
@@ -58,7 +58,6 @@ static int config(struct vf_instance *vf, int width, int height,
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char *args){
|
||||
vf->query_format=query_format;
|
||||
vf->draw_slice=vf_next_draw_slice;
|
||||
vf->default_caps=0;
|
||||
if (vf->priv->outfmt)
|
||||
vf->config=config;
|
||||
|
||||
@@ -47,7 +47,6 @@ static int query_format(struct vf_instance *vf, unsigned int fmt){
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char *args){
|
||||
vf->query_format=query_format;
|
||||
vf->draw_slice=vf_next_draw_slice;
|
||||
vf->default_caps=0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,6 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi)
|
||||
mpi->stride[2] = c->stride[2];
|
||||
|
||||
mpi->flags |= MP_IMGFLAG_DIRECT;
|
||||
mpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ static int config(struct vf_instance *vf,
|
||||
}
|
||||
if (vf->priv->direction & 4){
|
||||
vf->put_image=vf_next_put_image; // passthru mode!
|
||||
if (vf->next->draw_slice) vf->draw_slice=vf_next_draw_slice;
|
||||
/* FIXME: this should be in an other procedure in vf.c; that should always check
|
||||
whether the filter after the passthrough one still (not)supports slices */
|
||||
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
|
||||
|
||||
@@ -47,7 +47,6 @@ static struct vf_priv_s {
|
||||
double param[2];
|
||||
unsigned int fmt;
|
||||
struct SwsContext *ctx;
|
||||
struct SwsContext *ctx2; //for interlaced slices only
|
||||
unsigned char* palette;
|
||||
int interlaced;
|
||||
int noup;
|
||||
@@ -60,7 +59,6 @@ static struct vf_priv_s {
|
||||
{SWS_PARAM_DEFAULT, SWS_PARAM_DEFAULT},
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -301,7 +299,6 @@ static int config(struct vf_instance *vf,
|
||||
|
||||
// free old ctx:
|
||||
if(vf->priv->ctx) sws_freeContext(vf->priv->ctx);
|
||||
if(vf->priv->ctx2)sws_freeContext(vf->priv->ctx2);
|
||||
|
||||
// new swscaler:
|
||||
sws_getFlagsAndFilterFromCmdLine(&int_sws_flags, &srcFilter, &dstFilter);
|
||||
@@ -312,13 +309,6 @@ static int config(struct vf_instance *vf,
|
||||
vf->priv->w, vf->priv->h >> vf->priv->interlaced,
|
||||
dfmt,
|
||||
int_sws_flags, srcFilter, dstFilter, vf->priv->param);
|
||||
if(vf->priv->interlaced){
|
||||
vf->priv->ctx2=sws_getContext(width, height >> 1,
|
||||
sfmt,
|
||||
vf->priv->w, vf->priv->h >> 1,
|
||||
dfmt,
|
||||
int_sws_flags, srcFilter, dstFilter, vf->priv->param);
|
||||
}
|
||||
if(!vf->priv->ctx){
|
||||
// error...
|
||||
mp_msg(MSGT_VFILTER,MSGL_WARN,"Couldn't init SwScaler for this setup\n");
|
||||
@@ -388,16 +378,6 @@ static int config(struct vf_instance *vf,
|
||||
return vf_next_config(vf,vf->priv->w,vf->priv->h,d_width,d_height,flags,best);
|
||||
}
|
||||
|
||||
static void start_slice(struct vf_instance *vf, mp_image_t *mpi){
|
||||
// printf("start_slice called! flag=%d\n",mpi->flags&MP_IMGFLAG_DRAW_CALLBACK);
|
||||
if(!(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)) return; // shouldn't happen
|
||||
// they want slices!!! allocate the buffer.
|
||||
mpi->priv=vf->dmpi=vf_get_image(vf->next,vf->priv->fmt,
|
||||
// mpi->type, mpi->flags & (~MP_IMGFLAG_DRAW_CALLBACK),
|
||||
MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
|
||||
vf->priv->w, vf->priv->h);
|
||||
}
|
||||
|
||||
static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src[MP_MAX_PLANES], int src_stride[MP_MAX_PLANES],
|
||||
int y, int h, uint8_t *dst[MP_MAX_PLANES], int dst_stride[MP_MAX_PLANES], int interlaced){
|
||||
const uint8_t *src2[MP_MAX_PLANES]={src[0], src[1], src[2], src[3]};
|
||||
@@ -428,24 +408,13 @@ static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_slice(struct vf_instance *vf,
|
||||
unsigned char** src, int* stride, int w,int h, int x, int y){
|
||||
mp_image_t *dmpi=vf->dmpi;
|
||||
if(!dmpi){
|
||||
mp_msg(MSGT_VFILTER,MSGL_FATAL,"vf_scale: draw_slice() called with dmpi=NULL (no get_image?)\n");
|
||||
return;
|
||||
}
|
||||
// printf("vf_scale::draw_slice() y=%d h=%d\n",y,h);
|
||||
scale(vf->priv->ctx, vf->priv->ctx2, src, stride, y, h, dmpi->planes, dmpi->stride, vf->priv->interlaced);
|
||||
}
|
||||
|
||||
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
|
||||
mp_image_t *dmpi=mpi->priv;
|
||||
|
||||
// printf("vf_scale::put_image(): processing whole frame! dmpi=%p flag=%d\n",
|
||||
// dmpi, (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK));
|
||||
|
||||
if(!(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK && dmpi)){
|
||||
if(!dmpi){
|
||||
|
||||
// hope we'll get DR buffer:
|
||||
dmpi=vf_get_image(vf->next,vf->priv->fmt,
|
||||
@@ -512,17 +481,11 @@ static int control(struct vf_instance *vf, int request, void* data){
|
||||
|
||||
r= sws_setColorspaceDetails(vf->priv->ctx, inv_table, srcRange, table, dstRange, brightness, contrast, saturation);
|
||||
if(r<0) break;
|
||||
if(vf->priv->ctx2){
|
||||
r= sws_setColorspaceDetails(vf->priv->ctx2, inv_table, srcRange, table, dstRange, brightness, contrast, saturation);
|
||||
if(r<0) break;
|
||||
}
|
||||
|
||||
return CONTROL_TRUE;
|
||||
case VFCTRL_SET_YUV_COLORSPACE: {
|
||||
struct mp_csp_details colorspace = *(struct mp_csp_details *)data;
|
||||
if (mp_sws_set_colorspace(vf->priv->ctx, &colorspace) >= 0) {
|
||||
if (vf->priv->ctx2)
|
||||
mp_sws_set_colorspace(vf->priv->ctx2, &colorspace);
|
||||
vf->priv->colorspace = colorspace;
|
||||
return 1;
|
||||
}
|
||||
@@ -619,15 +582,12 @@ static int query_format(struct vf_instance *vf, unsigned int fmt){
|
||||
|
||||
static void uninit(struct vf_instance *vf){
|
||||
if(vf->priv->ctx) sws_freeContext(vf->priv->ctx);
|
||||
if(vf->priv->ctx2) sws_freeContext(vf->priv->ctx2);
|
||||
free(vf->priv->palette);
|
||||
free(vf->priv);
|
||||
}
|
||||
|
||||
static int vf_open(vf_instance_t *vf, char *args){
|
||||
vf->config=config;
|
||||
vf->start_slice=start_slice;
|
||||
vf->draw_slice=draw_slice;
|
||||
vf->put_image=put_image;
|
||||
vf->query_format=query_format;
|
||||
vf->control= control;
|
||||
|
||||
@@ -37,7 +37,7 @@ struct vf_priv_s {
|
||||
mp_image_t *image;
|
||||
void (*image_callback)(void *, mp_image_t *);
|
||||
void *image_callback_ctx;
|
||||
int shot, store_slices;
|
||||
int shot;
|
||||
};
|
||||
|
||||
//===========================================================================//
|
||||
@@ -54,53 +54,8 @@ static int config(struct vf_instance *vf,
|
||||
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
|
||||
}
|
||||
|
||||
static void start_slice(struct vf_instance *vf, mp_image_t *mpi)
|
||||
{
|
||||
mpi->priv=
|
||||
vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
|
||||
mpi->type, mpi->flags, mpi->width, mpi->height);
|
||||
if (vf->priv->shot) {
|
||||
vf->priv->store_slices = 1;
|
||||
if (!(vf->priv->image->flags & MP_IMGFLAG_ALLOCATED))
|
||||
mp_image_alloc_planes(vf->priv->image);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void memcpy_pic_slice(unsigned char *dst, unsigned char *src,
|
||||
int bytesPerLine, int y, int h,
|
||||
int dstStride, int srcStride)
|
||||
{
|
||||
memcpy_pic(dst + h * dstStride, src + h * srcStride, bytesPerLine,
|
||||
h, dstStride, srcStride);
|
||||
}
|
||||
|
||||
static void draw_slice(struct vf_instance *vf, unsigned char** src,
|
||||
int* stride, int w,int h, int x, int y)
|
||||
{
|
||||
if (vf->priv->store_slices) {
|
||||
mp_image_t *dst = vf->priv->image;
|
||||
int bp = (dst->bpp + 7) / 8;
|
||||
|
||||
if (dst->flags & MP_IMGFLAG_PLANAR) {
|
||||
int bytes_per_line[3] = { w * bp, dst->chroma_width, dst->chroma_width };
|
||||
for (int n = 0; n < 3; n++) {
|
||||
memcpy_pic_slice(dst->planes[n], src[n], bytes_per_line[n],
|
||||
y, h, dst->stride[n], stride[n]);
|
||||
}
|
||||
} else {
|
||||
memcpy_pic_slice(dst->planes[0], src[0], dst->w*bp, y, dst->h,
|
||||
dst->stride[0], stride[0]);
|
||||
}
|
||||
}
|
||||
vf_next_draw_slice(vf,src,stride,w,h,x,y);
|
||||
}
|
||||
|
||||
static void get_image(struct vf_instance *vf, mp_image_t *mpi)
|
||||
{
|
||||
// FIXME: should vf.c really call get_image when using slices??
|
||||
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
|
||||
return;
|
||||
vf->dmpi= vf_get_image(vf->next, mpi->imgfmt,
|
||||
mpi->type, mpi->flags/* | MP_IMGFLAG_READABLE*/, mpi->width, mpi->height);
|
||||
|
||||
@@ -119,7 +74,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
|
||||
{
|
||||
mp_image_t *dmpi = (mp_image_t *)mpi->priv;
|
||||
|
||||
if(!(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK))){
|
||||
if(!(mpi->flags&(MP_IMGFLAG_DIRECT))){
|
||||
dmpi=vf_get_image(vf->next,mpi->imgfmt,
|
||||
MP_IMGTYPE_EXPORT, 0,
|
||||
mpi->width, mpi->height);
|
||||
@@ -134,11 +89,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
|
||||
|
||||
if(vf->priv->shot) {
|
||||
vf->priv->shot=0;
|
||||
mp_image_t image;
|
||||
if (!vf->priv->store_slices)
|
||||
image = *dmpi;
|
||||
else
|
||||
image = *vf->priv->image;
|
||||
mp_image_t image = *dmpi;
|
||||
image.flags &= ~MP_IMGFLAG_ALLOCATED;
|
||||
image.w = vf->priv->image->w;
|
||||
image.h = vf->priv->image->h;
|
||||
@@ -146,7 +97,6 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
|
||||
image.display_w = vf->priv->image->display_w;
|
||||
image.display_h = vf->priv->image->display_h;
|
||||
vf->priv->image_callback(vf->priv->image_callback_ctx, &image);
|
||||
vf->priv->store_slices = 0;
|
||||
}
|
||||
|
||||
return vf_next_put_image(vf, dmpi, pts);
|
||||
@@ -188,13 +138,10 @@ static int vf_open(vf_instance_t *vf, char *args)
|
||||
vf->control=control;
|
||||
vf->put_image=put_image;
|
||||
vf->query_format=query_format;
|
||||
vf->start_slice=start_slice;
|
||||
vf->draw_slice=draw_slice;
|
||||
vf->get_image=get_image;
|
||||
vf->uninit=uninit;
|
||||
vf->priv=malloc(sizeof(struct vf_priv_s));
|
||||
vf->priv->shot=0;
|
||||
vf->priv->store_slices=0;
|
||||
vf->priv->image=NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -104,12 +104,6 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi)
|
||||
FFMAX(mpi->width, vf->priv->outw),
|
||||
FFMAX(mpi->height, vf->priv->outh));
|
||||
|
||||
if ((vf->dmpi->flags & MP_IMGFLAG_DRAW_CALLBACK) &&
|
||||
!(vf->dmpi->flags & MP_IMGFLAG_DIRECT)) {
|
||||
mp_tmsg(MSGT_ASS, MSGL_INFO, "Full DR not possible, trying SLICES instead!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int tmargin = vf->priv->opt_top_margin;
|
||||
// set up mpi as a cropped-down image of dmpi:
|
||||
if (mpi->flags & MP_IMGFLAG_PLANAR) {
|
||||
@@ -124,8 +118,6 @@ static void get_image(struct vf_instance *vf, mp_image_t *mpi)
|
||||
mpi->stride[0] = vf->dmpi->stride[0];
|
||||
mpi->width = vf->dmpi->width;
|
||||
mpi->flags |= MP_IMGFLAG_DIRECT;
|
||||
mpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK;
|
||||
// vf->dmpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
|
||||
}
|
||||
|
||||
static void blank(mp_image_t *mpi, int y1, int y2)
|
||||
@@ -155,8 +147,7 @@ static void blank(mp_image_t *mpi, int y1, int y2)
|
||||
static int prepare_image(struct vf_instance *vf, mp_image_t *mpi)
|
||||
{
|
||||
int tmargin = vf->priv->opt_top_margin;
|
||||
if (mpi->flags & MP_IMGFLAG_DIRECT
|
||||
|| mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) {
|
||||
if (mpi->flags & MP_IMGFLAG_DIRECT) {
|
||||
vf->dmpi = mpi->priv;
|
||||
if (!vf->dmpi) {
|
||||
mp_tmsg(MSGT_ASS, MSGL_WARN, "Why do we get NULL??\n");
|
||||
|
||||
@@ -37,9 +37,6 @@ struct vf_priv_s {
|
||||
};
|
||||
#define video_out (vf->priv->vo)
|
||||
|
||||
static void draw_slice(struct vf_instance *vf, unsigned char **src,
|
||||
int *stride, int w, int h, int x, int y);
|
||||
|
||||
static int config(struct vf_instance *vf,
|
||||
int width, int height, int d_width, int d_height,
|
||||
unsigned int flags, unsigned int outfmt)
|
||||
@@ -69,7 +66,6 @@ static int config(struct vf_instance *vf,
|
||||
|
||||
// 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;
|
||||
}
|
||||
@@ -140,21 +136,6 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
|
||||
return vo_draw_image(video_out, mpi, pts);
|
||||
}
|
||||
|
||||
static void start_slice(struct vf_instance *vf, mp_image_t *mpi)
|
||||
{
|
||||
if (!video_out->config_ok)
|
||||
return;
|
||||
vo_control(video_out, VOCTRL_START_SLICE, mpi);
|
||||
}
|
||||
|
||||
static void draw_slice(struct vf_instance *vf, unsigned char **src,
|
||||
int *stride, int w, int h, int x, int y)
|
||||
{
|
||||
if (!video_out->config_ok)
|
||||
return;
|
||||
vo_draw_slice(video_out, src, stride, w, h, x, y);
|
||||
}
|
||||
|
||||
static void uninit(struct vf_instance *vf)
|
||||
{
|
||||
if (vf->priv) {
|
||||
@@ -172,8 +153,6 @@ static int vf_open(vf_instance_t *vf, char *args)
|
||||
vf->query_format = query_format;
|
||||
vf->get_image = get_image;
|
||||
vf->put_image = put_image;
|
||||
vf->draw_slice = draw_slice;
|
||||
vf->start_slice = start_slice;
|
||||
vf->uninit = uninit;
|
||||
vf->priv = calloc(1, sizeof(struct vf_priv_s));
|
||||
vf->priv->vo = (struct vo *)args;
|
||||
|
||||
@@ -73,10 +73,6 @@
|
||||
|
||||
#define MP_IMGFLAGMASK_COLORS 0xF00
|
||||
|
||||
// codec uses drawing/rendering callbacks (draw_slice()-like thing, DR method 2)
|
||||
// [the codec will set this flag if it supports callbacks, and the vo _may_
|
||||
// clear it in get_image() if draw_slice() not implemented]
|
||||
#define MP_IMGFLAG_DRAW_CALLBACK 0x1000
|
||||
// set if it's in video buffer/memory: [set by vo/vf's get_image() !!!]
|
||||
#define MP_IMGFLAG_DIRECT 0x2000
|
||||
// set if buffer is allocated (used in destination images):
|
||||
|
||||
@@ -213,11 +213,6 @@ void vo_skip_frame(struct vo *vo)
|
||||
vo->frame_loaded = false;
|
||||
}
|
||||
|
||||
int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y)
|
||||
{
|
||||
return vo->driver->draw_slice(vo, src, stride, w, h, x, y);
|
||||
}
|
||||
|
||||
void vo_new_frame_imminent(struct vo *vo)
|
||||
{
|
||||
if (vo->driver->buffer_frames)
|
||||
|
||||
@@ -52,8 +52,6 @@ enum mp_voctrl {
|
||||
VOCTRL_GET_EQUALIZER, // struct voctrl_get_equalizer_args
|
||||
VOCTRL_DUPLICATE_FRAME,
|
||||
|
||||
VOCTRL_START_SLICE,
|
||||
|
||||
/* for vdpau hardware decoding */
|
||||
VOCTRL_HWDEC_DECODER_RENDER, // pointer to hw state
|
||||
|
||||
@@ -193,17 +191,6 @@ struct vo_driver {
|
||||
*/
|
||||
void (*get_buffered_frame)(struct vo *vo, bool eof);
|
||||
|
||||
/*
|
||||
* Draw a planar YUV slice to the buffer:
|
||||
* params:
|
||||
* src[3] = source image planes (Y,U,V)
|
||||
* stride[3] = source image planes line widths (in bytes)
|
||||
* w,h = width*height of area to be copied (in Y pixels)
|
||||
* x,y = position at the destination image (in Y pixels)
|
||||
*/
|
||||
int (*draw_slice)(struct vo *vo, uint8_t *src[], int stride[], int w,
|
||||
int h, int x, int y);
|
||||
|
||||
/*
|
||||
* Draws OSD to the screen buffer
|
||||
*/
|
||||
@@ -302,7 +289,6 @@ int vo_draw_image(struct vo *vo, struct mp_image *mpi, double pts);
|
||||
int vo_redraw_frame(struct vo *vo);
|
||||
int vo_get_buffered_frame(struct vo *vo, bool eof);
|
||||
void vo_skip_frame(struct vo *vo);
|
||||
int vo_draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h, int x, int y);
|
||||
void vo_new_frame_imminent(struct vo *vo);
|
||||
void vo_draw_osd(struct vo *vo, struct osd_state *osd);
|
||||
void vo_flip_page(struct vo *vo, unsigned int pts_us, int duration);
|
||||
|
||||
@@ -171,12 +171,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
mpi->planes[0]);
|
||||
}
|
||||
|
||||
static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h,
|
||||
int x, int y)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void flip_page(struct vo *vo)
|
||||
{
|
||||
if (showosdmessage) {
|
||||
@@ -380,7 +374,6 @@ const struct vo_driver video_out_caca = {
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_image = draw_image,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
.check_events = check_events,
|
||||
|
||||
@@ -246,7 +246,7 @@ static int query_format(struct vo *vo, uint32_t format)
|
||||
{
|
||||
struct priv *p = vo->priv;
|
||||
const int flags = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
|
||||
VFCAP_OSD | VOCAP_NOSLICES;
|
||||
VFCAP_OSD;
|
||||
switch (format) {
|
||||
case IMGFMT_YUY2:
|
||||
p->pixelFormat = kYUVSPixelFormat;
|
||||
|
||||
@@ -871,8 +871,7 @@ static void uninit_d3d(d3d_priv *priv)
|
||||
static void d3d_upload_and_render_frame_texture(d3d_priv *priv,
|
||||
mp_image_t *mpi)
|
||||
{
|
||||
if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK))
|
||||
draw_slice(priv->vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
|
||||
draw_slice(priv->vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
|
||||
|
||||
d3d_unlock_video_objects(priv);
|
||||
|
||||
@@ -894,9 +893,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
return;
|
||||
}
|
||||
|
||||
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
|
||||
goto skip_upload;
|
||||
|
||||
if (mpi->flags & MP_IMGFLAG_PLANAR) { /* Copy a planar frame. */
|
||||
draw_slice(priv->vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
|
||||
goto skip_upload;
|
||||
@@ -2069,7 +2065,6 @@ const struct vo_driver video_out_direct3d = {
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_image = draw_image,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
.check_events = check_events,
|
||||
@@ -2088,7 +2083,6 @@ const struct vo_driver video_out_direct3d_shaders = {
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_image = draw_image,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
.check_events = check_events,
|
||||
|
||||
@@ -200,10 +200,8 @@ static int query_format(struct vo *vo, uint32_t format)
|
||||
// we can do it
|
||||
VFCAP_CSP_SUPPORTED_BY_HW |
|
||||
// we don't convert colorspaces here
|
||||
VFCAP_OSD |
|
||||
VFCAP_OSD;
|
||||
// we have OSD
|
||||
VOCAP_NOSLICES;
|
||||
// we don't use slices
|
||||
}
|
||||
|
||||
static void write_packet(struct vo *vo, int size, AVPacket *packet)
|
||||
|
||||
@@ -30,12 +30,6 @@
|
||||
#include "video/vfcap.h"
|
||||
#include "video/mp_image.h"
|
||||
|
||||
static int draw_slice(struct vo *vo, uint8_t *image[], int stride[],
|
||||
int w, int h, int x, int y)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
{
|
||||
}
|
||||
@@ -96,7 +90,6 @@ const struct vo_driver video_out_null = {
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_image = draw_image,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
.check_events = check_events,
|
||||
|
||||
@@ -1237,26 +1237,6 @@ static void flip_page(struct vo *vo)
|
||||
p->frames_rendered++;
|
||||
}
|
||||
|
||||
static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h,
|
||||
int x, int y)
|
||||
{
|
||||
struct gl_priv *p = vo->priv;
|
||||
GL *gl = p->gl;
|
||||
|
||||
p->mpi_flipped = stride[0] < 0;
|
||||
|
||||
for (int n = 0; n < p->plane_count; n++) {
|
||||
gl->ActiveTexture(GL_TEXTURE0 + n);
|
||||
gl->BindTexture(GL_TEXTURE_2D, p->planes[n].gl_texture);
|
||||
int xs = p->planes[n].shift_x, ys = p->planes[n].shift_y;
|
||||
glUploadTex(gl, GL_TEXTURE_2D, p->gl_format, p->gl_type, src[n],
|
||||
stride[n], x >> xs, y >> ys, w >> xs, h >> ys, 0);
|
||||
}
|
||||
gl->ActiveTexture(GL_TEXTURE0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t get_image(struct vo *vo, mp_image_t *mpi)
|
||||
{
|
||||
struct gl_priv *p = vo->priv;
|
||||
@@ -1308,8 +1288,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
|
||||
mp_image_t mpi2 = *mpi;
|
||||
int w = mpi->w, h = mpi->h;
|
||||
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
|
||||
goto skip_upload;
|
||||
mpi2.flags = 0;
|
||||
mpi2.type = MP_IMGTYPE_TEMP;
|
||||
mpi2.width = mpi2.w;
|
||||
@@ -1347,7 +1325,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
}
|
||||
gl->ActiveTexture(GL_TEXTURE0);
|
||||
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
skip_upload:
|
||||
|
||||
do_render(p);
|
||||
}
|
||||
|
||||
@@ -2259,7 +2237,6 @@ const struct vo_driver video_out_opengl = {
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_image = draw_image,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
.check_events = check_events,
|
||||
@@ -2278,7 +2255,6 @@ const struct vo_driver video_out_opengl_hq = {
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_image = draw_image,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
.check_events = check_events,
|
||||
|
||||
@@ -587,29 +587,6 @@ static void flip_page(struct vo *vo)
|
||||
gl->Clear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h,
|
||||
int x, int y)
|
||||
{
|
||||
struct gl_priv *p = vo->priv;
|
||||
GL *gl = p->gl;
|
||||
|
||||
p->mpi_flipped = stride[0] < 0;
|
||||
glUploadTex(gl, p->target, p->gl_format, p->gl_type, src[0], stride[0],
|
||||
x, y, w, h, p->slice_height);
|
||||
if (p->is_yuv) {
|
||||
int xs, ys;
|
||||
mp_get_chroma_shift(p->image_format, &xs, &ys, NULL);
|
||||
gl->ActiveTexture(GL_TEXTURE1);
|
||||
glUploadTex(gl, p->target, p->gl_format, p->gl_type, src[1], stride[1],
|
||||
x >> xs, y >> ys, w >> xs, h >> ys, p->slice_height);
|
||||
gl->ActiveTexture(GL_TEXTURE2);
|
||||
glUploadTex(gl, p->target, p->gl_format, p->gl_type, src[2], stride[2],
|
||||
x >> xs, y >> ys, w >> xs, h >> ys, p->slice_height);
|
||||
gl->ActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t get_image(struct vo *vo, mp_image_t *mpi)
|
||||
{
|
||||
struct gl_priv *p = vo->priv;
|
||||
@@ -719,8 +696,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
unsigned char *planes[3];
|
||||
mp_image_t mpi2 = *mpi;
|
||||
int w = mpi->w, h = mpi->h;
|
||||
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
|
||||
goto skip_upload;
|
||||
mpi2.flags = 0;
|
||||
mpi2.type = MP_IMGTYPE_TEMP;
|
||||
mpi2.width = mpi2.w;
|
||||
@@ -807,7 +782,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
if (mpi->flags & MP_IMGFLAG_DIRECT) {
|
||||
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
skip_upload:
|
||||
|
||||
do_render(vo);
|
||||
}
|
||||
|
||||
@@ -1172,7 +1147,6 @@ const struct vo_driver video_out_opengl_old = {
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_image = draw_image,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
.check_events = check_events,
|
||||
|
||||
@@ -1309,7 +1309,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi, double pts)
|
||||
if (IMGFMT_IS_VDPAU(vc->image_format)) {
|
||||
rndr = mpi->priv;
|
||||
reserved_mpi = mpi;
|
||||
} else if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) {
|
||||
} else {
|
||||
rndr = get_surface(vo, vc->deint_counter);
|
||||
vc->deint_counter = WRAP_ADD(vc->deint_counter, 1, NUM_BUFFERED_VIDEO);
|
||||
if (handle_preemption(vo) >= 0) {
|
||||
@@ -1323,11 +1323,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi, double pts)
|
||||
CHECK_ST_WARNING("Error when calling "
|
||||
"vdp_video_surface_put_bits_y_cb_cr");
|
||||
}
|
||||
} else
|
||||
// We don't support slice callbacks so this shouldn't occur -
|
||||
// I think the flags test above in pointless, but I'm adding
|
||||
// this instead of removing it just in case.
|
||||
abort();
|
||||
}
|
||||
if (mpi->fields & MP_IMGFIELD_ORDERED)
|
||||
vc->top_field_first = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST);
|
||||
else
|
||||
@@ -1437,7 +1433,6 @@ static int query_format(struct vo *vo, uint32_t format)
|
||||
case IMGFMT_NV12:
|
||||
case IMGFMT_YUY2:
|
||||
case IMGFMT_UYVY:
|
||||
return default_flags | VOCAP_NOSLICES;
|
||||
case IMGFMT_VDPAU_MPEG1:
|
||||
case IMGFMT_VDPAU_MPEG2:
|
||||
case IMGFMT_VDPAU_H264:
|
||||
|
||||
@@ -300,7 +300,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
|
||||
}
|
||||
|
||||
/* set image size (which is indeed neither the input nor output size),
|
||||
if zoom is on it will be changed during draw_slice anyway so we don't
|
||||
if zoom is on it will be changed during draw_image anyway so we don't
|
||||
duplicate the aspect code here
|
||||
*/
|
||||
p->image_width = (width + 7) & (~7);
|
||||
@@ -474,8 +474,7 @@ static void flip_page(struct vo *vo)
|
||||
XSync(vo->x11->display, False);
|
||||
}
|
||||
|
||||
static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h,
|
||||
int x, int y)
|
||||
static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
{
|
||||
struct priv *p = vo->priv;
|
||||
uint8_t *dst[MP_MAX_PLANES] = {NULL};
|
||||
@@ -517,15 +516,9 @@ static int draw_slice(struct vo *vo, uint8_t *src[], int stride[], int w, int h,
|
||||
dst[0] += dstStride[0] * (p->image_height - 1);
|
||||
dstStride[0] = -dstStride[0];
|
||||
}
|
||||
sws_scale(p->swsContext, (const uint8_t **)src, stride, y, h, dst,
|
||||
dstStride);
|
||||
sws_scale(p->swsContext, (const uint8_t **)mpi->planes, mpi->stride,
|
||||
0, mpi->h, dst, dstStride);
|
||||
mp_draw_sub_backup_reset(p->osd_backup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
{
|
||||
draw_slice(vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
|
||||
}
|
||||
|
||||
static int query_format(struct vo *vo, uint32_t format)
|
||||
@@ -651,7 +644,6 @@ const struct vo_driver video_out_x11 = {
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_image = draw_image,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
.check_events = check_events,
|
||||
|
||||
@@ -445,9 +445,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
{
|
||||
struct xvctx *ctx = vo->priv;
|
||||
|
||||
if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
|
||||
; // done
|
||||
else if (mpi->flags & MP_IMGFLAG_PLANAR)
|
||||
if (mpi->flags & MP_IMGFLAG_PLANAR)
|
||||
draw_slice(vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
|
||||
else if (mpi->flags & MP_IMGFLAG_YUV)
|
||||
// packed YUV:
|
||||
@@ -694,7 +692,6 @@ const struct vo_driver video_out_xv = {
|
||||
.config = config,
|
||||
.control = control,
|
||||
.draw_image = draw_image,
|
||||
.draw_slice = draw_slice,
|
||||
.draw_osd = draw_osd,
|
||||
.flip_page = flip_page,
|
||||
.check_events = check_events,
|
||||
|
||||
@@ -36,7 +36,5 @@
|
||||
#define VFCAP_ACCEPT_STRIDE 0x400
|
||||
// filter does postprocessing (so you shouldn't scale/filter image before it)
|
||||
#define VFCAP_POSTPROC 0x800
|
||||
// used by libvo and vf_vo, indicates the VO does not support draw_slice for this format
|
||||
#define VOCAP_NOSLICES 0x8000
|
||||
|
||||
#endif /* MPLAYER_VFCAP_H */
|
||||
|
||||
Reference in New Issue
Block a user