2 * OSX Shared Buffer Video Output (extracted from mplayer's corevideo)
4 * This file is part of mplayer2.
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.
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.
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/>.
21 * This video output was extracted from mplayer's corevideo. It's purpose it
22 * to copy mp_image data to a shared buffer using mmap and to do simple
23 * coordination with the GUIs using Distributed Objects.
28 #include "vo_sharedbuffer.h"
29 #include "video_out.h"
30 #include "subopt-helper.h"
33 #include "libmpcodecs/vfcap.h"
34 #include "libmpcodecs/mp_image.h"
35 #include "fastmemcpy.h"
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,
52 NSDistantObject *mposx_proxy;
53 id <MPlayerOSXVOProto> mposx_proto;
59 static void draw_alpha(void *ctx, int x0, int y0, int w, int h,
60 unsigned char *src, unsigned char *srca,
63 p->vo_draw_alpha_fnc(w, h, src, srca, stride,
64 p->image_data + (x0 + y0 * p->image_width) * p->image_bytespp,
65 p->image_width * p->image_bytespp);
68 static unsigned int image_bytes()
70 return p->image_width * p->image_height * p->image_bytespp;
73 static int preinit(struct vo *vo, const char *arg)
75 p = talloc_zero(NULL, struct priv);
77 const opt_t subopts[] = {
78 {"buffer_name", OPT_ARG_MSTRZ, &p->buffer_name, NULL},
82 if (subopt_parse(arg, subopts) != 0) {
83 mp_msg(MSGT_VO, MSGL_FATAL,
84 "\n-vo sharedbuffer command line help:\n"
85 "Example: mplayer -vo shared_buffer:buffer_name=mybuff\n"
87 " buffer_name=<name>\n"
88 " Name of the shared buffer created with shm_open() as well as\n"
89 " the name of the NSConnection mplayer2 will try to open.\n"
90 "Example: mplayer -vo sharedbuffer\n"
95 if (!p->buffer_name) p->buffer_name = "mplayerosx";
100 static void flip_page(struct vo *vo)
102 NSAutoreleasePool *pool = [NSAutoreleasePool new];
103 [p->mposx_proto render];
107 static void check_events(struct vo *vo) { }
109 static uint32_t draw_image(struct vo *vo, mp_image_t *mpi)
111 memcpy_pic(p->image_data, mpi->planes[0],
112 (p->image_width) * (p->image_bytespp), p->image_height,
113 (p->image_width) * (p->image_bytespp), mpi->stride[0]);
117 static void draw_osd(struct vo *vo, struct osd_state *osd) {
118 osd_draw_text(osd, p->image_width, p->image_height, draw_alpha, vo);
121 static void free_buffers(void)
123 [p->mposx_proto stop];
124 p->mposx_proto = nil;
125 [p->mposx_proxy release];
126 p->mposx_proxy = nil;
129 if (munmap(p->image_data, image_bytes()) == -1)
130 mp_msg(MSGT_VO, MSGL_FATAL, "[vo_sharedbuffer] uninit: munmap "
131 "failed. Error: %s\n", strerror(errno));
133 if (shm_unlink(p->buffer_name) == -1)
134 mp_msg(MSGT_VO, MSGL_FATAL, "[vo_sharedbuffer] uninit: shm_unlink "
135 "failed. Error: %s\n", strerror(errno));
139 static int config(struct vo *vo, uint32_t width, uint32_t height,
140 uint32_t d_width, uint32_t d_height, uint32_t flags,
143 NSAutoreleasePool *pool = [NSAutoreleasePool new];
146 p->image_width = width;
147 p->image_height = height;
149 mp_msg(MSGT_VO, MSGL_INFO, "[vo_sharedbuffer] writing output to a shared "
150 "buffer named \"%s\"\n", p->buffer_name);
152 // create shared memory
153 int shm_fd = shm_open(p->buffer_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
155 mp_msg(MSGT_VO, MSGL_FATAL,
156 "[vo_sharedbuffer] failed to open shared memory. Error: %s\n",
161 if (ftruncate(shm_fd, image_bytes()) == -1) {
162 mp_msg(MSGT_VO, MSGL_FATAL,
163 "[vo_sharedbuffer] failed to size shared memory, possibly "
164 "already in use. Error: %s\n", strerror(errno));
166 shm_unlink(p->buffer_name);
170 p->image_data = mmap(NULL, image_bytes(),
171 PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
174 if (p->image_data == MAP_FAILED) {
175 mp_msg(MSGT_VO, MSGL_FATAL,
176 "[vo_sharedbuffer] failed to map shared memory. "
177 "Error: %s\n", strerror(errno));
178 shm_unlink(p->buffer_name);
182 //connect to mplayerosx
183 p->mposx_proxy = [NSConnection
184 rootProxyForConnectionWithRegisteredName:
185 [NSString stringWithUTF8String:p->buffer_name] host:nil];
187 if ([p->mposx_proxy conformsToProtocol:@protocol(MPlayerOSXVOProto)]) {
188 [p->mposx_proxy setProtocolForProxy:@protocol(MPlayerOSXVOProto)];
189 p->mposx_proto = (id <MPlayerOSXVOProto>)p->mposx_proxy;
190 [p->mposx_proto startWithWidth:p->image_width
191 withHeight:p->image_height
192 withBytes:p->image_bytespp
193 withAspect:d_width*100/d_height];
195 mp_msg(MSGT_VO, MSGL_ERR,
196 "[vo_sharedbuffer] distributed object doesn't conform "
197 "to the correct protocol.\n");
198 [p->mposx_proxy release];
199 p->mposx_proxy = nil;
200 p->mposx_proto = nil;
210 static int query_format(uint32_t format)
212 unsigned int image_depth = 0;
215 p->vo_draw_alpha_fnc = vo_draw_alpha_yuy2;
219 p->vo_draw_alpha_fnc = vo_draw_alpha_rgb24;
223 p->vo_draw_alpha_fnc = vo_draw_alpha_rgb32;
227 p->vo_draw_alpha_fnc = vo_draw_alpha_rgb32;
234 p->image_bytespp = (image_depth + 7) / 8;
235 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
236 VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN |
240 static void uninit(struct vo *vo)
245 static int control(struct vo *vo, uint32_t request, void *data)
248 case VOCTRL_DRAW_IMAGE:
249 return draw_image(vo, data);
250 case VOCTRL_FULLSCREEN:
251 [p->mposx_proto toggleFullscreen];
253 case VOCTRL_QUERY_FORMAT:
254 return query_format(*(uint32_t*)data);
256 [p->mposx_proto ontop];
262 const struct vo_driver video_out_sharedbuffer = {
264 .info = &(const vo_info_t) {
265 "Mac OS X Shared Buffer (headless video output for GUIs)",
267 "Stefano Pigozzi <stefano.pigozzi@gmail.com> and others.",
273 .flip_page = flip_page,
274 .check_events = check_events,