video: remove lowres support, cut "too slow" message
[mplayer.git] / libvo / vo_sharedbuffer.m
blob40aa170864668990792d1ddc2ea922ba9d58e85f
1 /*
2  * OSX Shared Buffer Video Output (extracted from mplayer's corevideo)
3  *
4  * This file is part of mplayer2.
5  *
6  * mplayer2 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * mplayer2 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with mplayer2.  If not, see <http://www.gnu.org/licenses/>.
18  */
21  * This video output was extracted from mplayer's corevideo. Its purpose is
22  * to copy mp_image data to a shared buffer using mmap and to do simple
23  * coordination with the GUIs using Distributed Objects.
24  */
26 #include <sys/mman.h>
28 #include "vo_sharedbuffer.h"
29 #include "video_out.h"
30 #include "m_option.h"
31 #include "talloc.h"
33 #include "libmpcodecs/vfcap.h"
34 #include "libmpcodecs/mp_image.h"
35 #include "fastmemcpy.h"
37 #include "sub/sub.h"
38 #include "osd.h"
40 // declarations
41 struct priv {
42     char *buffer_name;
43     unsigned char *image_data;
44     unsigned int image_bytespp;
45     unsigned int image_width;
46     unsigned int image_height;
48     void (*vo_draw_alpha_fnc)(int w, int h, unsigned char* src,
49         unsigned char *srca, int srcstride, unsigned char* dstbase,
50         int dststride);
52     NSDistantObject *mposx_proxy;
53     id <MPlayerOSXVOProto> mposx_proto;
56 // implementation
57 static void draw_alpha(void *ctx, int x0, int y0, int w, int h,
58                             unsigned char *src, unsigned char *srca,
59                             int stride)
61     struct priv *p = ((struct vo *) ctx)->priv;
62     p->vo_draw_alpha_fnc(w, h, src, srca, stride,
63         p->image_data + (x0 + y0 * p->image_width) * p->image_bytespp,
64         p->image_width * p->image_bytespp);
67 static unsigned int image_bytes(struct priv *p)
69     return p->image_width * p->image_height * p->image_bytespp;
72 static int preinit(struct vo *vo, const char *arg)
74     return 0;
77 static void flip_page(struct vo *vo)
79     struct priv *p = vo->priv;
80     NSAutoreleasePool *pool = [NSAutoreleasePool new];
81     [p->mposx_proto render];
82     [pool release];
85 static void check_events(struct vo *vo) { }
87 static uint32_t draw_image(struct vo *vo, mp_image_t *mpi)
89     struct priv *p = vo->priv;
90     memcpy_pic(p->image_data, mpi->planes[0],
91                (p->image_width) * (p->image_bytespp), p->image_height,
92                (p->image_width) * (p->image_bytespp), mpi->stride[0]);
93     return 0;
96 static void draw_osd(struct vo *vo, struct osd_state *osd) {
97     struct priv *p = vo->priv;
98     osd_draw_text(osd, p->image_width, p->image_height, draw_alpha, vo);
101 static void free_buffers(struct priv *p)
103     [p->mposx_proto stop];
104     p->mposx_proto = nil;
105     [p->mposx_proxy release];
106     p->mposx_proxy = nil;
108     if (p->image_data) {
109         if (munmap(p->image_data, image_bytes(p)) == -1)
110             mp_msg(MSGT_VO, MSGL_FATAL, "[vo_sharedbuffer] uninit: munmap "
111                                         "failed. Error: %s\n", strerror(errno));
113         if (shm_unlink(p->buffer_name) == -1)
114             mp_msg(MSGT_VO, MSGL_FATAL, "[vo_sharedbuffer] uninit: shm_unlink "
115                                         "failed. Error: %s\n", strerror(errno));
116     }
119 static int config(struct vo *vo, uint32_t width, uint32_t height,
120                   uint32_t d_width, uint32_t d_height, uint32_t flags,
121                   uint32_t format)
123     struct priv *p = vo->priv;
124     NSAutoreleasePool *pool = [NSAutoreleasePool new];
125     free_buffers(p);
127     p->image_width = width;
128     p->image_height = height;
130     mp_msg(MSGT_VO, MSGL_INFO, "[vo_sharedbuffer] writing output to a shared "
131         "buffer named \"%s\"\n", p->buffer_name);
133     // create shared memory
134     int shm_fd = shm_open(p->buffer_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
135     if (shm_fd == -1) {
136         mp_msg(MSGT_VO, MSGL_FATAL,
137             "[vo_sharedbuffer] failed to open shared memory. Error: %s\n",
138             strerror(errno));
139         goto err_out;
140     }
142     if (ftruncate(shm_fd, image_bytes(p)) == -1) {
143         mp_msg(MSGT_VO, MSGL_FATAL,
144             "[vo_sharedbuffer] failed to size shared memory, possibly "
145             "already in use. Error: %s\n", strerror(errno));
146         close(shm_fd);
147         shm_unlink(p->buffer_name);
148         goto err_out;
149     }
151     p->image_data = mmap(NULL, image_bytes(p),
152         PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
153     close(shm_fd);
155     if (p->image_data == MAP_FAILED) {
156         mp_msg(MSGT_VO, MSGL_FATAL,
157             "[vo_sharedbuffer] failed to map shared memory. "
158             "Error: %s\n", strerror(errno));
159         shm_unlink(p->buffer_name);
160         goto err_out;
161     }
163     //connect to mplayerosx
164     p->mposx_proxy = [NSConnection
165         rootProxyForConnectionWithRegisteredName:
166                   [NSString stringWithUTF8String:p->buffer_name] host:nil];
168     if ([p->mposx_proxy conformsToProtocol:@protocol(MPlayerOSXVOProto)]) {
169         [p->mposx_proxy setProtocolForProxy:@protocol(MPlayerOSXVOProto)];
170         p->mposx_proto = (id <MPlayerOSXVOProto>)p->mposx_proxy;
171         [p->mposx_proto startWithWidth:p->image_width
172                             withHeight:p->image_height
173                              withBytes:p->image_bytespp
174                             withAspect:d_width*100/d_height];
175     } else {
176         mp_msg(MSGT_VO, MSGL_ERR,
177             "[vo_sharedbuffer] distributed object doesn't conform "
178             "to the correct protocol.\n");
179         [p->mposx_proxy release];
180         p->mposx_proxy = nil;
181         p->mposx_proto = nil;
182     }
184     [pool release];
185     return 0;
186 err_out:
187     [pool release];
188     return 1;
191 static int query_format(struct vo *vo, uint32_t format)
193     struct priv *p = vo->priv;
194     unsigned int image_depth = 0;
195     switch (format) {
196     case IMGFMT_YUY2:
197         p->vo_draw_alpha_fnc = vo_draw_alpha_yuy2;
198         image_depth = 16;
199         goto supported;
200     case IMGFMT_RGB24:
201         p->vo_draw_alpha_fnc = vo_draw_alpha_rgb24;
202         image_depth = 24;
203         goto supported;
204     case IMGFMT_ARGB:
205         p->vo_draw_alpha_fnc = vo_draw_alpha_rgb32;
206         image_depth = 32;
207         goto supported;
208     case IMGFMT_BGRA:
209         p->vo_draw_alpha_fnc = vo_draw_alpha_rgb32;
210         image_depth = 32;
211         goto supported;
212     }
213     return 0;
215 supported:
216     p->image_bytespp = (image_depth + 7) / 8;
217     return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
218         VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN |
219         VOCAP_NOSLICES;
222 static void uninit(struct vo *vo)
224     struct priv *p = vo->priv;
225     free_buffers(p);
228 static int control(struct vo *vo, uint32_t request, void *data)
230     struct priv *p = vo->priv;
231     switch (request) {
232         case VOCTRL_DRAW_IMAGE:
233             return draw_image(vo, data);
234         case VOCTRL_FULLSCREEN:
235             [p->mposx_proto toggleFullscreen];
236             return VO_TRUE;
237         case VOCTRL_QUERY_FORMAT:
238             return query_format(vo, *(uint32_t*)data);
239         case VOCTRL_ONTOP:
240             [p->mposx_proto ontop];
241             return VO_TRUE;
242     }
243     return VO_NOTIMPL;
246 #undef OPT_BASE_STRUCT
247 #define OPT_BASE_STRUCT struct priv
249 const struct vo_driver video_out_sharedbuffer = {
250     .is_new = true,
251     .info = &(const vo_info_t) {
252         "Mac OS X Shared Buffer (headless video output for GUIs)",
253         "sharedbuffer",
254         "Stefano Pigozzi <stefano.pigozzi@gmail.com> and others.",
255         ""
256     },
257     .preinit = preinit,
258     .config = config,
259     .control = control,
260     .flip_page = flip_page,
261     .check_events = check_events,
262     .uninit = uninit,
263     .draw_osd = draw_osd,
264     .privsize = sizeof(struct priv),
265     .options = (const struct m_option[]) {
266         OPT_STRING("buffer_name", buffer_name, 0, OPTDEF_STR("mplayerosx")),
267         {NULL},
268     },