Skip to content

Commit db6dbb3

Browse files
committed
Add patch
1 parent 9ca9066 commit db6dbb3

File tree

5 files changed

+591
-0
lines changed

5 files changed

+591
-0
lines changed

video/out/vo.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ extern const struct vo_driver video_out_wlshm;
6565
extern const struct vo_driver video_out_rpi;
6666
extern const struct vo_driver video_out_tct;
6767
extern const struct vo_driver video_out_sixel;
68+
extern const struct vo_driver video_out_sharedbuffer;
69+
extern const struct vo_driver video_out_shm;
6870

6971
const struct vo_driver *const video_out_drivers[] =
7072
{
@@ -111,6 +113,12 @@ const struct vo_driver *const video_out_drivers[] =
111113
&video_out_sixel,
112114
#endif
113115
&video_out_lavc,
116+
#if HAVE_COCOA
117+
&video_out_sharedbuffer,
118+
#endif
119+
#if HAVE_POSIX
120+
&video_out_shm,
121+
#endif
114122
NULL
115123
};
116124

video/out/vo_sharedbuffer.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
*/
19+
20+
#ifndef MPLAYER_VO_OSX_SHAREDBUFFER_H
21+
#define MPLAYER_VO_OSX_SHAREDBUFFER_H
22+
23+
#import <Cocoa/Cocoa.h>
24+
25+
// Protocol to communicate with the GUI
26+
@protocol MPlayerOSXVOProto
27+
- (int) startWithWidth: (bycopy int)width
28+
withHeight: (bycopy int)height
29+
withBytes: (bycopy int)bytes
30+
withAspect: (bycopy int)aspect;
31+
- (void) stop;
32+
- (void) render;
33+
- (void) toggleFullscreen;
34+
- (void) ontop;
35+
@end
36+
37+
#endif /* MPLAYER_VO_OSX_SHAREDBUFFER_H */

video/out/vo_sharedbuffer.m

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
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+
*/
19+
20+
/*
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+
*/
25+
26+
27+
#include "vo_sharedbuffer.h"
28+
#include "vo.h"
29+
#include "video/mp_image.h"
30+
#include "sub/osd.h"
31+
32+
#include <sys/mman.h>
33+
#include <sys/stat.h>
34+
#include <fcntl.h>
35+
#include <errno.h>
36+
#include <unistd.h>
37+
38+
39+
// declarations
40+
struct priv {
41+
char *buffer_name;
42+
unsigned char *image_data;
43+
uint32_t image_bytes;
44+
uint32_t image_width;
45+
uint32_t image_height;
46+
uint32_t image_format;
47+
uint32_t image_stride;
48+
uint32_t buffer_size;
49+
50+
NSDistantObject *mposx_proxy;
51+
id <MPlayerOSXVOProto> mposx_proto;
52+
};
53+
54+
55+
static int preinit(struct vo *vo)
56+
{
57+
MP_INFO(vo, "preinit \n");
58+
return 0;
59+
}
60+
61+
static void flip_page(struct vo *vo)
62+
{
63+
//MP_INFO(vo, "flip_page \n");
64+
65+
struct priv *p = vo->priv;
66+
NSAutoreleasePool *pool = [NSAutoreleasePool new];
67+
[p->mposx_proto render];
68+
[pool release];
69+
}
70+
71+
static void draw_image(struct vo *vo, mp_image_t *mpi)
72+
{
73+
//MP_INFO(vo, "draw_image \n");
74+
75+
struct priv *p = vo->priv;
76+
struct mp_osd_res dim = osd_res_from_image_params(vo->params);
77+
osd_draw_on_image(vo->osd, dim, mpi->pts, 0, mpi);
78+
79+
if (p->image_format == IMGFMT_420P) {
80+
unsigned char * ptr = p->image_data;
81+
int size = p->image_stride * p->image_height;
82+
memcpy_pic(ptr, mpi->planes[0], p->image_width, p->image_height, p->image_stride, mpi->stride[0]);
83+
ptr += size;
84+
size = (p->image_width * p->image_height) / 2;
85+
memcpy_pic(ptr, mpi->planes[1], p->image_width / 2, p->image_height / 2, p->image_width / 2, mpi->stride[1]);
86+
ptr += size;
87+
memcpy_pic(ptr, mpi->planes[2], p->image_width / 2, p->image_height / 2, p->image_width / 2, mpi->stride[2]);
88+
} else {
89+
memcpy_pic(p->image_data, mpi->planes[0],
90+
p->image_width * p->image_bytes, p->image_height,
91+
p->image_stride, mpi->stride[0]);
92+
}
93+
talloc_free(mpi);
94+
}
95+
96+
static void free_buffers(struct vo *vo)
97+
{
98+
struct priv *p = vo->priv;
99+
[p->mposx_proto stop];
100+
p->mposx_proto = nil;
101+
[p->mposx_proxy release];
102+
p->mposx_proxy = nil;
103+
104+
if (p->image_data) {
105+
if (munmap(p->image_data, p->buffer_size) == -1) {
106+
MP_FATAL(vo, "uninit: munmap failed. Error: %s\n", strerror(errno));
107+
}
108+
if (shm_unlink(p->buffer_name) == -1) {
109+
MP_FATAL(vo, "uninit: shm_unlink failed. Error: %s\n", strerror(errno));
110+
}
111+
}
112+
}
113+
114+
static int reconfig(struct vo *vo, struct mp_image_params *params)
115+
{
116+
MP_INFO(vo, "reconfig w: %d h: %d format: %d \n", params->w, params->h, params->imgfmt);
117+
118+
struct priv *p = vo->priv;
119+
NSAutoreleasePool *pool = [NSAutoreleasePool new];
120+
free_buffers(vo);
121+
122+
p->image_width = params->w;
123+
p->image_height = params->h;
124+
p->image_format = params->imgfmt;
125+
126+
switch (p->image_format)
127+
{
128+
case IMGFMT_RGB24:
129+
p->image_bytes = 3;
130+
break;
131+
case IMGFMT_RGB565:
132+
p->image_bytes = 2;
133+
break;
134+
case IMGFMT_420P:
135+
p->image_bytes = 1;
136+
break;
137+
case IMGFMT_NV12:
138+
case IMGFMT_UYVY:
139+
p->image_bytes = 2;
140+
break;
141+
default:
142+
p->image_bytes = 3;
143+
}
144+
p->image_stride = p->image_width * p->image_bytes;
145+
p->buffer_size = p->image_stride * p->image_height;
146+
if (p->image_format == IMGFMT_420P) {
147+
p->buffer_size = p->image_width * p->image_height * 2;
148+
}
149+
150+
MP_INFO(vo, "writing output to a shared buffer named \"%s\"\n", p->buffer_name);
151+
152+
// create shared memory
153+
int shm_fd = shm_open(p->buffer_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
154+
if (shm_fd == -1) {
155+
MP_FATAL(vo, "failed to open shared memory. Error: %s\n", strerror(errno));
156+
goto err_out;
157+
}
158+
159+
MP_INFO(vo, "dw: %d dh: %d\n", vo->dwidth, vo->dheight);
160+
MP_INFO(vo, "w: %d h: %d bytes: %d buffer size: %d\n", p->image_width, p->image_height, p->image_bytes, p->buffer_size);
161+
162+
if (ftruncate(shm_fd, p->buffer_size) == -1) {
163+
close(shm_fd);
164+
shm_unlink(p->buffer_name);
165+
goto err_out;
166+
}
167+
168+
p->image_data = mmap(NULL, p->buffer_size,
169+
PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
170+
close(shm_fd);
171+
172+
if (p->image_data == MAP_FAILED) {
173+
MP_FATAL(vo, "failed to map shared memory. Error: %s\n", strerror(errno));
174+
shm_unlink(p->buffer_name);
175+
goto err_out;
176+
}
177+
178+
//connect to mplayerosx
179+
p->mposx_proxy = [NSConnection
180+
rootProxyForConnectionWithRegisteredName:
181+
[NSString stringWithUTF8String:p->buffer_name] host:nil];
182+
183+
if ([p->mposx_proxy conformsToProtocol:@protocol(MPlayerOSXVOProto)]) {
184+
[p->mposx_proxy setProtocolForProxy:@protocol(MPlayerOSXVOProto)];
185+
p->mposx_proto = (id <MPlayerOSXVOProto>)p->mposx_proxy;
186+
[p->mposx_proto startWithWidth:p->image_width
187+
withHeight:p->image_height
188+
withBytes:p->image_bytes
189+
withAspect:vo->dwidth*100/vo->dheight];
190+
} else {
191+
MP_ERR(vo, "distributed object doesn't conform to the correct protocol.\n");
192+
[p->mposx_proxy release];
193+
p->mposx_proxy = nil;
194+
p->mposx_proto = nil;
195+
}
196+
197+
[pool release];
198+
return 0;
199+
err_out:
200+
[pool release];
201+
return -1;
202+
}
203+
204+
static int query_format(struct vo *vo, int format)
205+
{
206+
//MP_INFO(vo, "query_format: %d \n", format);
207+
208+
switch (format) {
209+
case IMGFMT_420P:
210+
//case IMGFMT_YUY2:
211+
case IMGFMT_UYVY:
212+
case IMGFMT_RGB24:
213+
//case IMGFMT_ARGB:
214+
//case IMGFMT_BGRA:
215+
return 1;
216+
}
217+
return 0;
218+
}
219+
220+
static void uninit(struct vo *vo)
221+
{
222+
free_buffers(vo);
223+
}
224+
225+
static int control(struct vo *vo, uint32_t request, void *data)
226+
{
227+
//MP_INFO(vo, "control: request: %d \n", request);
228+
return VO_NOTIMPL;
229+
}
230+
231+
232+
#undef OPT_BASE_STRUCT
233+
#define OPT_BASE_STRUCT struct priv
234+
235+
const struct vo_driver video_out_sharedbuffer = {
236+
.name = "sharedbuffer",
237+
.description = "Mac OS X Shared Buffer (headless video output for GUIs)",
238+
.preinit = preinit,
239+
.reconfig = reconfig,
240+
.control = control,
241+
.flip_page = flip_page,
242+
.query_format = query_format,
243+
.draw_image = draw_image,
244+
.uninit = uninit,
245+
.priv_size = sizeof(struct priv),
246+
.options = (const struct m_option[]) {
247+
{"name", OPT_STRING(buffer_name)},
248+
{0}
249+
},
250+
.priv_defaults = &(const struct priv) {
251+
.buffer_name = "mpv",
252+
},
253+
.options_prefix = "sharedbuffer",
254+
};

0 commit comments

Comments
 (0)