2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "img_format.h"
31 #include "fmt-conversion.h"
32 #include "libvo/fastmemcpy.h"
34 #include <libswscale/swscale.h>
38 void (*image_callback
)(void *, mp_image_t
*);
39 void *image_callback_ctx
;
40 int shot
, store_slices
;
43 //===========================================================================//
45 static int config(struct vf_instance
*vf
,
46 int width
, int height
, int d_width
, int d_height
,
47 unsigned int flags
, unsigned int outfmt
)
49 free_mp_image(vf
->priv
->image
);
50 vf
->priv
->image
= new_mp_image(width
, height
);
51 mp_image_setfmt(vf
->priv
->image
, outfmt
);
52 vf
->priv
->image
->w
= d_width
;
53 vf
->priv
->image
->h
= d_height
;
54 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
57 static void start_slice(struct vf_instance
*vf
, mp_image_t
*mpi
)
59 vf
->dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
60 mpi
->type
, mpi
->flags
, mpi
->width
, mpi
->height
);
62 vf
->priv
->store_slices
= 1;
63 if (!(vf
->priv
->image
->flags
& MP_IMGFLAG_ALLOCATED
))
64 mp_image_alloc_planes(vf
->priv
->image
);
69 static void memcpy_pic_slice(unsigned char *dst
, unsigned char *src
,
70 int bytesPerLine
, int y
, int h
,
71 int dstStride
, int srcStride
)
73 memcpy_pic(dst
+ h
* dstStride
, src
+ h
* srcStride
, bytesPerLine
,
74 h
, dstStride
, srcStride
);
77 static void draw_slice(struct vf_instance
*vf
, unsigned char** src
,
78 int* stride
, int w
,int h
, int x
, int y
)
80 if (vf
->priv
->store_slices
) {
81 mp_image_t
*dst
= vf
->priv
->image
;
82 int bp
= (dst
->bpp
+ 7) / 8;
84 if (dst
->flags
& MP_IMGFLAG_PLANAR
) {
85 int bytes_per_line
[3] = { w
* bp
, dst
->chroma_width
, dst
->chroma_width
};
86 for (int n
= 0; n
< 3; n
++) {
87 memcpy_pic_slice(dst
->planes
[n
], src
[n
], bytes_per_line
[n
],
88 y
, h
, dst
->stride
[n
], stride
[n
]);
91 memcpy_pic_slice(dst
->planes
[0], src
[0], dst
->w
*bp
, y
, dst
->h
,
92 dst
->stride
[0], stride
[0]);
95 vf_next_draw_slice(vf
,src
,stride
,w
,h
,x
,y
);
98 static void get_image(struct vf_instance
*vf
, mp_image_t
*mpi
)
100 // FIXME: should vf.c really call get_image when using slices??
101 if (mpi
->flags
& MP_IMGFLAG_DRAW_CALLBACK
)
103 vf
->dmpi
= vf_get_image(vf
->next
, mpi
->imgfmt
,
104 mpi
->type
, mpi
->flags
/* | MP_IMGFLAG_READABLE*/, mpi
->width
, mpi
->height
);
106 for (int i
= 0; i
< MP_MAX_PLANES
; i
++) {
107 mpi
->planes
[i
]=vf
->dmpi
->planes
[i
];
108 mpi
->stride
[i
]=vf
->dmpi
->stride
[i
];
110 mpi
->width
=vf
->dmpi
->width
;
112 mpi
->flags
|=MP_IMGFLAG_DIRECT
;
114 mpi
->priv
=(void*)vf
->dmpi
;
117 static int put_image(struct vf_instance
*vf
, mp_image_t
*mpi
, double pts
)
119 mp_image_t
*dmpi
= (mp_image_t
*)mpi
->priv
;
121 if (mpi
->flags
& MP_IMGFLAG_DRAW_CALLBACK
)
124 if(!(mpi
->flags
&MP_IMGFLAG_DIRECT
)){
125 dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
126 MP_IMGTYPE_EXPORT
, 0,
127 mpi
->width
, mpi
->height
);
128 vf_clone_mpi_attributes(dmpi
, mpi
);
129 for (int i
= 0; i
< MP_MAX_PLANES
; i
++) {
130 dmpi
->planes
[i
]=mpi
->planes
[i
];
131 dmpi
->stride
[i
]=mpi
->stride
[i
];
133 dmpi
->width
=mpi
->width
;
134 dmpi
->height
=mpi
->height
;
140 if (!vf
->priv
->store_slices
)
143 image
= *vf
->priv
->image
;
144 image
.w
= vf
->priv
->image
->w
;
145 image
.h
= vf
->priv
->image
->h
;
146 vf
->priv
->image_callback(vf
->priv
->image_callback_ctx
, &image
);
147 vf
->priv
->store_slices
= 0;
150 return vf_next_put_image(vf
, dmpi
, pts
);
153 static int control (vf_instance_t
*vf
, int request
, void *data
)
155 if(request
==VFCTRL_SCREENSHOT
) {
156 struct vf_ctrl_screenshot
*cmd
= (struct vf_ctrl_screenshot
*)data
;
157 vf
->priv
->image_callback
= cmd
->image_callback
;
158 vf
->priv
->image_callback_ctx
= cmd
->image_callback_ctx
;
162 return vf_next_control (vf
, request
, data
);
166 //===========================================================================//
168 static int query_format(struct vf_instance
*vf
, unsigned int fmt
)
170 enum PixelFormat av_format
= imgfmt2pixfmt(fmt
);
172 if (av_format
!= PIX_FMT_NONE
&& sws_isSupportedInput(av_format
))
173 return vf_next_query_format(vf
, fmt
);
177 static void uninit(vf_instance_t
*vf
)
179 free_mp_image(vf
->priv
->image
);
183 static int vf_open(vf_instance_t
*vf
, char *args
)
187 vf
->put_image
=put_image
;
188 vf
->query_format
=query_format
;
189 vf
->start_slice
=start_slice
;
190 vf
->draw_slice
=draw_slice
;
191 vf
->get_image
=get_image
;
193 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
195 vf
->priv
->store_slices
=0;
196 vf
->priv
->image
=NULL
;
201 const vf_info_t vf_info_screenshot
= {
202 "screenshot to file",
204 "A'rpi, Jindrich Makovicka",
210 //===========================================================================//