sd_ass: initialize structs for external tracks properly
[mplayer.git] / libmpcodecs / vf_screenshot.c
blob7f9a45c8791da5dd00e7757d59b5e1eb4c29e0b3
1 /*
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.
19 #include "config.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <inttypes.h>
26 #include "mp_msg.h"
27 #include "img_format.h"
28 #include "mp_image.h"
29 #include "vf.h"
30 #include "vf_scale.h"
31 #include "fmt-conversion.h"
32 #include "libvo/fastmemcpy.h"
34 #include <libswscale/swscale.h>
36 struct vf_priv_s {
37 mp_image_t *image;
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);
61 if (vf->priv->shot) {
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]);
90 } else {
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)
102 return;
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)
122 dmpi = vf->dmpi;
123 else
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;
137 if(vf->priv->shot) {
138 vf->priv->shot=0;
139 mp_image_t image;
140 if (!vf->priv->store_slices)
141 image = *dmpi;
142 else
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;
159 vf->priv->shot=1;
160 return CONTROL_TRUE;
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);
174 return 0;
177 static void uninit(vf_instance_t *vf)
179 free_mp_image(vf->priv->image);
180 free(vf->priv);
183 static int vf_open(vf_instance_t *vf, char *args)
185 vf->config=config;
186 vf->control=control;
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;
192 vf->uninit=uninit;
193 vf->priv=malloc(sizeof(struct vf_priv_s));
194 vf->priv->shot=0;
195 vf->priv->store_slices=0;
196 vf->priv->image=NULL;
197 return 1;
201 const vf_info_t vf_info_screenshot = {
202 "screenshot to file",
203 "screenshot",
204 "A'rpi, Jindrich Makovicka",
206 vf_open,
207 NULL
210 //===========================================================================//