summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rwxr-xr-xconfigure26
-rw-r--r--libvo/video_out.c4
-rw-r--r--libvo/vo_sharedbuffer.h37
-rw-r--r--libvo/vo_sharedbuffer.m277
5 files changed, 345 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 43d04464a7..dacff8b690 100644
--- a/Makefile
+++ b/Makefile
@@ -437,6 +437,7 @@ SRCS_MPLAYER-$(BL) += libvo/vo_bl.c
SRCS_MPLAYER-$(CACA) += libvo/vo_caca.c
SRCS_MPLAYER-$(COREAUDIO) += libao2/ao_coreaudio.c
SRCS_MPLAYER-$(COREVIDEO) += libvo/vo_corevideo.m libvo/osx_common.c
+SRCS_MPLAYER-$(SHAREDBUFFER) += libvo/vo_sharedbuffer.m
SRCS_MPLAYER-$(DGA) += libvo/vo_dga.c
SRCS_MPLAYER-$(DIRECT3D) += libvo/vo_direct3d.c libvo/w32_common.c
SRCS_MPLAYER-$(DIRECTFB) += libvo/vo_directfb2.c libvo/vo_dfbmga.c
diff --git a/configure b/configure
index f9a4bbaafe..22926751e9 100755
--- a/configure
+++ b/configure
@@ -435,6 +435,7 @@ Video output:
--disable-yuv4mpeg disable yuv4mpeg video output [enable]
--disable-corevideo disable CoreVideo video output [autodetect]
--disable-cocoa disable Cocoa OpenGL backend [autodetect]
+ --disable-sharedbuffer disable OSX shared buffer video output [autodetect]
Audio output:
--disable-alsa disable ALSA audio output [autodetect]
@@ -691,6 +692,7 @@ _qtx=auto
_coreaudio=auto
_corevideo=auto
_cocoa=auto
+_sharedbuffer=auto
quicktime=auto
_macosx_finder=no
_macosx_bundle=auto
@@ -1120,6 +1122,8 @@ for ac_option do
--disable-corevideo) _corevideo=no ;;
--enable-cocoa) _cocoa=yes ;;
--disable-cocoa) _cocoa=no ;;
+ --enable-sharedbuffer) _sharedbuffer=yes ;;
+ --disable-sharedbuffer) _sharedbuffer=no ;;
--enable-macosx-finder) _macosx_finder=yes ;;
--disable-macosx-finder) _macosx_finder=no ;;
--enable-macosx-bundle) _macosx_bundle=yes ;;
@@ -4223,6 +4227,26 @@ else
fi
echores "$_corevideo"
+echocheck "SharedBuffer"
+if test "$_sharedbuffer" = auto ; then
+ cat > $TMPC <<EOF
+int main(void) {
+ NSApplicationLoad();
+}
+EOF
+ _sharedbuffer=no
+ cc_check -framework Cocoa && _sharedbuffer=yes
+fi
+if test "$_sharedbuffer" = yes ; then
+ vomodules="sharedbuffer $vomodules"
+ libs_mplayer="$libs_mplayer -framework Cocoa"
+ def_sharedbuffer='#define CONFIG_SHAREDBUFFER 1'
+else
+ novomodules="sharedbuffer $novomodules"
+ def_sharedbuffer='#undef CONFIG_SHAREDBUFFER'
+fi
+echores "$_sharedbuffer"
+
fi #if darwin
@@ -6361,6 +6385,7 @@ CDDA = $_cdda
CDDB = $_cddb
COREAUDIO = $_coreaudio
COREVIDEO = $_corevideo
+SHAREDBUFFER = $_sharedbuffer
DGA = $_dga
DIRECT3D = $_direct3d
DIRECTFB = $_directfb
@@ -6760,6 +6785,7 @@ $def_aa
$def_bl
$def_caca
$def_corevideo
+$def_sharedbuffer
$def_dga
$def_dga1
$def_dga2
diff --git a/libvo/video_out.c b/libvo/video_out.c
index 82fe4f8550..96a5220645 100644
--- a/libvo/video_out.c
+++ b/libvo/video_out.c
@@ -117,6 +117,7 @@ extern struct vo_driver video_out_tdfx_vid;
extern struct vo_driver video_out_xvr100;
extern struct vo_driver video_out_tga;
extern struct vo_driver video_out_corevideo;
+extern struct vo_driver video_out_sharedbuffer;
extern struct vo_driver video_out_pnm;
extern struct vo_driver video_out_md5sum;
@@ -180,6 +181,9 @@ const struct vo_driver *video_out_drivers[] =
#if (defined CONFIG_GL && !defined CONFIG_GL_COCOA)
&video_out_gl,
#endif
+#ifdef CONFIG_SHAREDBUFFER
+ &video_out_sharedbuffer,
+#endif
#ifdef CONFIG_GL_SDL
&video_out_gl_sdl,
#endif
diff --git a/libvo/vo_sharedbuffer.h b/libvo/vo_sharedbuffer.h
new file mode 100644
index 0000000000..c25463aa0a
--- /dev/null
+++ b/libvo/vo_sharedbuffer.h
@@ -0,0 +1,37 @@
+/*
+ * OSX Shared Buffer Video Output (extracted from mplayer's corevideo)
+ *
+ * This file is part of mplayer2.
+ *
+ * mplayer2 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mplayer2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mplayer2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MPLAYER_VO_OSX_SHAREDBUFFER_H
+#define MPLAYER_VO_OSX_SHAREDBUFFER_H
+
+#import <Cocoa/Cocoa.h>
+
+// Protocol to communicate with the GUI
+@protocol MPlayerOSXVOProto
+- (int) startWithWidth: (bycopy int)width
+ withHeight: (bycopy int)height
+ withBytes: (bycopy int)bytes
+ withAspect: (bycopy int)aspect;
+- (void) stop;
+- (void) render;
+- (void) toggleFullscreen;
+- (void) ontop;
+@end
+
+#endif /* MPLAYER_VO_OSX_SHAREDBUFFER_H */
diff --git a/libvo/vo_sharedbuffer.m b/libvo/vo_sharedbuffer.m
new file mode 100644
index 0000000000..0b811f1848
--- /dev/null
+++ b/libvo/vo_sharedbuffer.m
@@ -0,0 +1,277 @@
+/*
+ * OSX Shared Buffer Video Output (extracted from mplayer's corevideo)
+ *
+ * This file is part of mplayer2.
+ *
+ * mplayer2 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mplayer2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mplayer2. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This video output was extracted from mplayer's corevideo. It's purpose it
+ * to copy mp_image data to a shared buffer using mmap and to do simple
+ * coordination with the GUIs using Distributed Objects.
+ */
+
+#include <sys/mman.h>
+
+#include "vo_sharedbuffer.h"
+#include "video_out.h"
+#include "subopt-helper.h"
+#include "talloc.h"
+
+#include "libmpcodecs/vfcap.h"
+#include "libmpcodecs/mp_image.h"
+#include "fastmemcpy.h"
+
+#include "sub/sub.h"
+#include "osd.h"
+
+// declarations
+struct priv {
+ char *buffer_name;
+ unsigned char *image_data;
+ unsigned int image_bytespp;
+ unsigned int image_width;
+ unsigned int image_height;
+
+ void (*vo_draw_alpha_fnc)(int w, int h, unsigned char* src,
+ unsigned char *srca, int srcstride, unsigned char* dstbase,
+ int dststride);
+
+ NSDistantObject *mposx_proxy;
+ id <MPlayerOSXVOProto> mposx_proto;
+};
+
+struct priv *p;
+
+// implementation
+static void draw_alpha(void *ctx, int x0, int y0, int w, int h,
+ unsigned char *src, unsigned char *srca,
+ int stride)
+{
+ p->vo_draw_alpha_fnc(w, h, src, srca, stride,
+ p->image_data + (x0 + y0 * p->image_width) * p->image_bytespp,
+ p->image_width * p->image_bytespp);
+}
+
+static unsigned int image_bytes()
+{
+ return p->image_width * p->image_height * p->image_bytespp;
+}
+
+static int preinit(struct vo *vo, const char *arg)
+{
+ p = talloc_zero(NULL, struct priv);
+
+ const opt_t subopts[] = {
+ {"buffer_name", OPT_ARG_MSTRZ, &p->buffer_name, NULL},
+ {NULL}
+ };
+
+ if (subopt_parse(arg, subopts) != 0) {
+ mp_msg(MSGT_VO, MSGL_FATAL,
+ "\n-vo sharedbuffer command line help:\n"
+ "Example: mplayer -vo shared_buffer:buffer_name=mybuff\n"
+ "\nOptions:\n"
+ " buffer_name=<name>\n"
+ " Name of the shared buffer created with shm_open() as well as\n"
+ " the name of the NSConnection mplayer2 will try to open.\n"
+ "Example: mplayer -vo sharedbuffer\n"
+ "\n" );
+ return -1;
+ }
+
+ if (!p->buffer_name) p->buffer_name = "mplayerosx";
+
+ return 0;
+}
+
+static void flip_page(struct vo *vo)
+{
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+ [p->mposx_proto render];
+ [pool release];
+}
+
+static void check_events(struct vo *vo) { }
+
+static uint32_t draw_image(struct vo *vo, mp_image_t *mpi)
+{
+ memcpy_pic(p->image_data, mpi->planes[0],
+ (p->image_width) * (p->image_bytespp), p->image_height,
+ (p->image_width) * (p->image_bytespp), mpi->stride[0]);
+ return 0;
+}
+
+static void draw_osd(struct vo *vo, struct osd_state *osd) {
+ osd_draw_text(osd, p->image_width, p->image_height, draw_alpha, vo);
+}
+
+static void free_buffers(void)
+{
+ [p->mposx_proto stop];
+ p->mposx_proto = nil;
+ [p->mposx_proxy release];
+ p->mposx_proxy = nil;
+
+ if (p->image_data) {
+ if (munmap(p->image_data, image_bytes()) == -1)
+ mp_msg(MSGT_VO, MSGL_FATAL, "[vo_sharedbuffer] uninit: munmap "
+ "failed. Error: %s\n", strerror(errno));
+
+ if (shm_unlink(p->buffer_name) == -1)
+ mp_msg(MSGT_VO, MSGL_FATAL, "[vo_sharedbuffer] uninit: shm_unlink "
+ "failed. Error: %s\n", strerror(errno));
+ }
+}
+
+static int config(struct vo *vo, uint32_t width, uint32_t height,
+ uint32_t d_width, uint32_t d_height, uint32_t flags,
+ uint32_t format)
+{
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+ free_buffers();
+
+ p->image_width = width;
+ p->image_height = height;
+
+ mp_msg(MSGT_VO, MSGL_INFO, "[vo_sharedbuffer] writing output to a shared "
+ "buffer named \"%s\"\n", p->buffer_name);
+
+ // create shared memory
+ int shm_fd = shm_open(p->buffer_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+ if (shm_fd == -1) {
+ mp_msg(MSGT_VO, MSGL_FATAL,
+ "[vo_sharedbuffer] failed to open shared memory. Error: %s\n",
+ strerror(errno));
+ goto err_out;
+ }
+
+ if (ftruncate(shm_fd, image_bytes()) == -1) {
+ mp_msg(MSGT_VO, MSGL_FATAL,
+ "[vo_sharedbuffer] failed to size shared memory, possibly "
+ "already in use. Error: %s\n", strerror(errno));
+ close(shm_fd);
+ shm_unlink(p->buffer_name);
+ goto err_out;
+ }
+
+ p->image_data = mmap(NULL, image_bytes(),
+ PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
+ close(shm_fd);
+
+ if (p->image_data == MAP_FAILED) {
+ mp_msg(MSGT_VO, MSGL_FATAL,
+ "[vo_sharedbuffer] failed to map shared memory. "
+ "Error: %s\n", strerror(errno));
+ shm_unlink(p->buffer_name);
+ goto err_out;
+ }
+
+ //connect to mplayerosx
+ p->mposx_proxy = [NSConnection
+ rootProxyForConnectionWithRegisteredName:
+ [NSString stringWithUTF8String:p->buffer_name] host:nil];
+
+ if ([p->mposx_proxy conformsToProtocol:@protocol(MPlayerOSXVOProto)]) {
+ [p->mposx_proxy setProtocolForProxy:@protocol(MPlayerOSXVOProto)];
+ p->mposx_proto = (id <MPlayerOSXVOProto>)p->mposx_proxy;
+ [p->mposx_proto startWithWidth:p->image_width
+ withHeight:p->image_height
+ withBytes:p->image_bytespp
+ withAspect:d_width*100/d_height];
+ } else {
+ mp_msg(MSGT_VO, MSGL_ERR,
+ "[vo_sharedbuffer] distributed object doesn't conform "
+ "to the correct protocol.\n");
+ [p->mposx_proxy release];
+ p->mposx_proxy = nil;
+ p->mposx_proto = nil;
+ }
+
+ [pool release];
+ return 0;
+err_out:
+ [pool release];
+ return 1;
+}
+
+static int query_format(uint32_t format)
+{
+ unsigned int image_depth = 0;
+ switch (format) {
+ case IMGFMT_YUY2:
+ p->vo_draw_alpha_fnc = vo_draw_alpha_yuy2;
+ image_depth = 16;
+ goto supported;
+ case IMGFMT_RGB24:
+ p->vo_draw_alpha_fnc = vo_draw_alpha_rgb24;
+ image_depth = 24;
+ goto supported;
+ case IMGFMT_ARGB:
+ p->vo_draw_alpha_fnc = vo_draw_alpha_rgb32;
+ image_depth = 32;
+ goto supported;
+ case IMGFMT_BGRA:
+ p->vo_draw_alpha_fnc = vo_draw_alpha_rgb32;
+ image_depth = 32;
+ goto supported;
+ }
+ return 0;
+
+supported:
+ p->image_bytespp = (image_depth + 7) / 8;
+ return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
+ VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN |
+ VOCAP_NOSLICES;
+}
+
+static void uninit(struct vo *vo)
+{
+ free_buffers();
+}
+
+static int control(struct vo *vo, uint32_t request, void *data)
+{
+ switch (request) {
+ case VOCTRL_DRAW_IMAGE:
+ return draw_image(vo, data);
+ case VOCTRL_FULLSCREEN:
+ [p->mposx_proto toggleFullscreen];
+ return VO_TRUE;
+ case VOCTRL_QUERY_FORMAT:
+ return query_format(*(uint32_t*)data);
+ case VOCTRL_ONTOP:
+ [p->mposx_proto ontop];
+ return VO_TRUE;
+ }
+ return VO_NOTIMPL;
+}
+
+const struct vo_driver video_out_sharedbuffer = {
+ .is_new = true,
+ .info = &(const vo_info_t) {
+ "Mac OS X Shared Buffer (headless video output for GUIs)",
+ "sharedbuffer",
+ "Stefano Pigozzi <stefano.pigozzi@gmail.com> and others.",
+ ""
+ },
+ .preinit = preinit,
+ .config = config,
+ .control = control,
+ .flip_page = flip_page,
+ .check_events = check_events,
+ .uninit = uninit,
+ .draw_osd = draw_osd
+};