[MPlayer-dev-eng] [PATCH] Support for QNX: QSA audio and Photon GUI.
Mike Gorchak
mike.gorchak.qnx at gmail.com
Sun Feb 3 21:23:11 CET 2013
Hi,
Here is a patch (made against latest repository snapshot) to enable
native QNX support in the mplayer. This
patch contains QNX Sound Architecture (QSA) audio driver and Photon GUI
YUV/RGB renderer.
I've posted previous patch a week ago, but it seems ignored. This
patch has many improvements comparing to previous.
Thanks in advance!
diff -u -r -N mplayer-export-2013-02-03-orig/DOCS/man/en/mplayer.1
mplayer-export-2013-02-03/DOCS/man/en/mplayer.1
--- mplayer-export-2013-02-03-orig/DOCS/man/en/mplayer.1 2013-01-31
07:24:25.000000000 +0200
+++ mplayer-export-2013-02-03/DOCS/man/en/mplayer.1 2013-02-03
18:46:04.000000000 +0200
@@ -3575,7 +3575,7 @@
movie to make it fit a 4:3 display without black bands).
The range controls how much of the image is cropped.
Only works with the directx, xv, xmga, mga, gl, gl_tiled, quartz,
-corevideo and xvidix video output drivers.
+corevideo, photon and xvidix video output drivers.
.br
.I NOTE:
Values between \-1 and 0 are allowed as well, but highly experimental
diff -u -r -N mplayer-export-2013-02-03-orig/DOCS/tech/MAINTAINERS
mplayer-export-2013-02-03/DOCS/tech/MAINTAINERS
--- mplayer-export-2013-02-03-orig/DOCS/tech/MAINTAINERS 2013-01-31
07:24:25.000000000 +0200
+++ mplayer-export-2013-02-03/DOCS/tech/MAINTAINERS 2013-02-03
19:01:04.000000000 +0200
@@ -175,6 +175,7 @@
* vo_mga.c - None
* vo_mpegpes.c - None
* vo_null.c - None
+ * vo_photon.c - Mike Gorchak
* vo_png.c - Felix BГјnemann
* vo_pnm.c - Ivo van Poorten
* vo_quartz.c - Nicolas Plourde
@@ -216,6 +217,7 @@
* ao_pcm.c - None
* ao_plugin.c - None
* ao_pulse.c - None
+ * ao_qsa.c - Mike Gorchak
* ao_sdl.c - None
* ao_sgi.c - None
* ao_sun.c - None
diff -u -r -N mplayer-export-2013-02-03-orig/DOCS/xml/en/ports.xml
mplayer-export-2013-02-03/DOCS/xml/en/ports.xml
--- mplayer-export-2013-02-03-orig/DOCS/xml/en/ports.xml 2013-01-31
07:24:21.000000000 +0200
+++ mplayer-export-2013-02-03/DOCS/xml/en/ports.xml 2013-02-03
18:59:41.000000000 +0200
@@ -497,7 +497,19 @@
<title>QNX</title>
<para>
-You'll need to download and install SDL for QNX. Then run
+By default configure script will detect Photon GUI and QSA audio interface
+automatically. After successfull build you can run
<application>MPlayer</application>
+with <option>-vo photon</option> and <option>-ao qsa</option> options.
+</para>
+
+<para>
+Photon driver supports three methods of video output: direct layer
access (fastest),
+hardware offscreen blitter (fast), software offscreen blitter (slow,
but works with
+every graphics driver on every platform).
+</para>
+
+<para>
+As alternative, you'll need to download and install SDL for QNX. Then run
<application>MPlayer</application> with <option>-vo sdl:driver=photon</option>
and <option>-ao sdl:nto</option> options, it should be fast.
</para>
diff -u -r -N mplayer-export-2013-02-03-orig/DOCS/xml/it/ports.xml
mplayer-export-2013-02-03/DOCS/xml/it/ports.xml
--- mplayer-export-2013-02-03-orig/DOCS/xml/it/ports.xml 2013-01-31
07:24:21.000000000 +0200
+++ mplayer-export-2013-02-03/DOCS/xml/it/ports.xml 2013-02-03
18:59:41.000000000 +0200
@@ -497,7 +497,19 @@
<title>QNX</title>
<para>
-You'll need to download and install SDL for QNX. Then run
+By default configure script will detect Photon GUI and QSA audio interface
+automatically. After successfull build you can run
<application>MPlayer</application>
+with <option>-vo photon</option> and <option>-ao qsa</option> options.
+</para>
+
+<para>
+Photon driver supports three methods of video output: direct layer
access (fastest),
+hardware offscreen blitter (fast), software offscreen blitter (slow,
but works with
+every graphics driver on every platform).
+</para>
+
+<para>
+As alternative, you'll need to download and install SDL for QNX. Then run
<application>MPlayer</application> with <option>-vo sdl:driver=photon</option>
and <option>-ao sdl:nto</option> options, it should be fast.
</para>
diff -u -r -N mplayer-export-2013-02-03-orig/DOCS/xml/zh_CN/ports.xml
mplayer-export-2013-02-03/DOCS/xml/zh_CN/ports.xml
--- mplayer-export-2013-02-03-orig/DOCS/xml/zh_CN/ports.xml 2013-01-31
07:24:21.000000000 +0200
+++ mplayer-export-2013-02-03/DOCS/xml/zh_CN/ports.xml 2013-02-03
18:59:41.000000000 +0200
@@ -497,7 +497,19 @@
<title>QNX</title>
<para>
-You'll need to download and install SDL for QNX. Then run
+By default configure script will detect Photon GUI and QSA audio interface
+automatically. After successfull build you can run
<application>MPlayer</application>
+with <option>-vo photon</option> and <option>-ao qsa</option> options.
+</para>
+
+<para>
+Photon driver supports three methods of video output: direct layer
access (fastest),
+hardware offscreen blitter (fast), software offscreen blitter (slow,
but works with
+every graphics driver on every platform).
+</para>
+
+<para>
+As alternative, you'll need to download and install SDL for QNX. Then run
<application>MPlayer</application> with <option>-vo sdl:driver=photon</option>
and <option>-ao sdl:nto</option> options, it should be fast.
</para>
diff -u -r -N mplayer-export-2013-02-03-orig/Makefile
mplayer-export-2013-02-03/Makefile
--- mplayer-export-2013-02-03-orig/Makefile 2013-01-31 07:24:06.000000000 +0200
+++ mplayer-export-2013-02-03/Makefile 2013-02-03 15:53:50.000000000 +0200
@@ -560,6 +560,7 @@
SRCS_MPLAYER-$(OSS) += libao2/ao_oss.c
SRCS_MPLAYER-$(PNM) += libvo/vo_pnm.c
SRCS_MPLAYER-$(PULSE) += libao2/ao_pulse.c
+SRCS_MPLAYER-$(QSA) += libao2/ao_qsa.c
SRCS_MPLAYER-$(QUARTZ) += libvo/vo_quartz.c libvo/osx_common.c
SRCS_MPLAYER-$(S3FB) += libvo/vo_s3fb.c
SRCS_MPLAYER-$(SDL) += libao2/ao_sdl.c libvo/vo_sdl.c
libvo/sdl_common.c
@@ -573,6 +574,7 @@
SRCS_MPLAYER-$(V4L2) += libao2/ao_v4l2.c
SRCS_MPLAYER-$(VDPAU) += libvo/vo_vdpau.c
SRCS_MPLAYER-$(VESA) += libvo/gtf.c libvo/vo_vesa.c libvo/vesa_lvo.c
+SRCS_MPLAYER-$(PHOTON) += libvo/vo_photon.c
SRCS_MPLAYER-$(VIDIX) += libvo/vo_cvidix.c \
libvo/vosub_vidix.c \
vidix/vidix.c \
diff -u -r -N mplayer-export-2013-02-03-orig/configure
mplayer-export-2013-02-03/configure
--- mplayer-export-2013-02-03-orig/configure 2013-01-31 07:24:20.000000000 +0200
+++ mplayer-export-2013-02-03/configure 2013-02-03 15:37:06.000000000 +0200
@@ -524,6 +524,7 @@
--enable-bl enable Blinkenlights video output [disable]
--enable-tdfxvid enable tdfx_vid video output [disable]
--enable-xvr100 enable SUN XVR-100 video output [autodetect]
+ --enable-photon enable Photon video output [autodetect]
--disable-tga disable Targa video output [enable]
--disable-pnm disable PNM video output [enable]
--disable-md5sum disable md5sum video output [enable]
@@ -546,6 +547,7 @@
--disable-dart disable DART audio output [autodetect]
--disable-win32waveout disable Windows waveout audio output [autodetect]
--disable-coreaudio disable CoreAudio audio output [autodetect]
+ --disable-qsa disable QSA audio output [autodetect]
--disable-select disable using select() on the audio device [enable]
Language options:
@@ -731,6 +733,7 @@
_caca=auto
_svga=auto
_vesa=auto
+_photon=auto
_fbdev=auto
_dvb=auto
_dxr2=auto
@@ -796,6 +799,7 @@
_sgiaudio=auto
_sunaudio=auto
_alsa=auto
+_qsa=auto
_fastmemcpy=yes
hardcoded_tables=no
_unrar_exec=auto
@@ -1098,6 +1102,8 @@
--disable-svga) _svga=no ;;
--enable-vesa) _vesa=yes ;;
--disable-vesa) _vesa=no ;;
+ --enable-photon) _photon=yes ;;
+ --disable-photon) _photon=no ;;
--enable-fbdev) _fbdev=yes ;;
--disable-fbdev) _fbdev=no ;;
--enable-dvb) _dvb=yes ;;
@@ -1226,6 +1232,8 @@
--disable-sgiaudio) _sgiaudio=no ;;
--enable-alsa) _alsa=yes ;;
--disable-alsa) _alsa=no ;;
+ --enable-qsa) _qsa=yes ;;
+ --disable-qsa) _qsa=no ;;
--enable-tv) _tv=yes ;;
--disable-tv) _tv=no ;;
--enable-tv-bsdbt848) _tv_bsdbt848=yes ;;
@@ -1710,10 +1718,6 @@
extra_cflags="-DNEWLIB -D__USE_INLINE__ $extra_cflags"
fi
-if qnx ; then
- extra_ldflags="$extra_ldflags -lph"
-fi
-
if os2 ; then
_exesuf=".exe"
_getch=getch2-os2.c
@@ -3986,6 +3990,19 @@
fi #if sunos
+if qnx; then
+echocheck "dcmd_cam.h (QNX)"
+_qnx_cam=no
+header_check sys/dcmd_cam.h && _qnx_cam=yes
+if test "$_qnx_cam" = yes ; then
+ def_qnx_cam='#define QNX_DCMD_CAM_H 1'
+else
+ def_qnx_cam='#undef QNX_DCMD_CAM_H'
+fi
+echores "$_qnx_cam"
+fi #if qnx
+
+
echocheck "termcap"
if test "$_termcap" = auto ; then
_termcap=no
@@ -5184,6 +5201,23 @@
fi
echores "$_vesa"
+
+echocheck "Photon support"
+if test "$_photon" = auto ; then
+ _photon=no
+ statement_check Pt.h 'PtInit(NULL)' -lph && _photon=yes
+fi
+if test "$_photon" = yes ; then
+ def_photon='#define CONFIG_PHOTON 1'
+ libs_mplayer="$libs_mplayer -lph"
+ vomodules="photon $vomodules"
+else
+ def_photon='#undef CONFIG_PHOTON'
+ novomodules="photon $novomodules"
+fi
+echores "$_photon"
+
+
#################
# VIDEO + AUDIO #
#################
@@ -5747,6 +5781,22 @@
echores "$_alsa"
+echocheck "QSA audio"
+if test "$_qsa" = auto ; then
+ _qsa=no
+ header_check sys/asoundlib.h -lasound $ld_dl $ld_pthread && _qsa=yes
+fi
+if test "$_qsa" = yes ; then
+ aomodules="qsa $aomodules"
+ def_alsa='#define CONFIG_QSA 1'
+ extra_ldflags="$extra_ldflags -lasound"
+else
+ noaomodules="qsa $noaomodules"
+ def_alsa='#undef CONFIG_QSA'
+fi
+echores "$_qsa"
+
+
echocheck "Sun audio"
if test "$_sunaudio" = auto ; then
cat > $TMPC << EOF
@@ -5861,6 +5911,8 @@
default_cdrom_device="/dev/disk1"
elif dragonfly ; then
default_cdrom_device="/dev/cd0"
+elif qnx ; then
+ default_cdrom_device="/dev/cd0"
elif freebsd ; then
default_cdrom_device="/dev/acd0"
elif openbsd ; then
@@ -5875,7 +5927,7 @@
default_cdrom_device="/dev/cdrom"
fi
-if win32 || os2 || dragonfly || freebsd || openbsd || sunos || amigaos ; then
+if win32 || os2 || dragonfly || freebsd || openbsd || sunos ||
amigaos || qnx ; then
default_dvd_device=$default_cdrom_device
elif darwin ; then
default_dvd_device="/dev/rdiskN"
@@ -5924,9 +5976,9 @@
if test "$_dvdread_internal" = auto ; then
_dvdread_internal=no
_dvdread=no
- if (linux || freebsd || netbsd || openbsd || dragonfly || sunos || hpux) &&
+ if (linux || freebsd || netbsd || openbsd || dragonfly || sunos ||
hpux || qnx) &&
(test "$_dvd" = yes || test "$_cdrom" = yes || test "$_cdio" = yes ||
- test "$_dvdio" = yes || test "$_bsdi_dvd" = yes) ||
+ test "$_dvdio" = yes || test "$_bsdi_dvd" = yes || test
"$_qnx_cam" = yes) ||
darwin || win32 || os2; then
_dvdread_internal=yes
_dvdread=yes
@@ -8335,12 +8387,14 @@
OPENAL = $_openal
OSS = $_ossaudio
PE_EXECUTABLE = $_pe_executable
+PHOTON = $_photon
PNG = $_png
PNM = $_pnm
POSTPROC = $postproc
PRIORITY = $_priority
PULSE = $_pulse
PVR = $_pvr
+QSA = $_qsa
QTX_CODECS = $_qtx
QTX_CODECS_WIN32 = $_qtx_codecs_win32
QTX_EMULATION = $_qtx_emulation
@@ -8771,6 +8825,7 @@
$def_ossaudio_devdsp
$def_ossaudio_devmixer
$def_pulse
+$def_qsa
$def_sgiaudio
$def_sunaudio
$def_win32waveout
@@ -8867,6 +8922,7 @@
$def_mga
$def_mlib
$def_mng
+$def_photon
$def_postproc
$def_png
$def_pnm
diff -u -r -N mplayer-export-2013-02-03-orig/cpudetect.c
mplayer-export-2013-02-03/cpudetect.c
--- mplayer-export-2013-02-03-orig/cpudetect.c 2013-01-31
07:24:14.000000000 +0200
+++ mplayer-export-2013-02-03/cpudetect.c 2013-01-24 14:04:50.000000000 +0200
@@ -46,6 +46,9 @@
#include <os2.h>
#elif defined(__AMIGAOS4__)
#include <proto/exec.h>
+#elif defined(__QNXNTO__) && defined(__X86__)
+#include <x86/cpuinline.h>
+#include <sys/syspage.h>
#endif
/* Thanks to the FreeBSD project for some of this cpuid code, and
@@ -216,6 +219,19 @@
mp_msg(MSGT_CPUDETECT,MSGL_WARN, "Cannot test OS support for SSE,
disabling to be safe.\n" );
gCpuCaps.hasSSE=0;
#endif /* _POSIX_SOURCE */
+#elif defined(__QNXNTO__) && defined(__X86__)
+ mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE... " );
+ if ((__cpu_flags & X86_CPU_SIMD)==X86_CPU_SIMD)
+ {
+ gCpuCaps.hasSSE=1;
+ }
+ mp_msg(MSGT_CPUDETECT,MSGL_V, gCpuCaps.hasSSE ? "yes.\n" : "no!\n" );
+ mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE2... " );
+ if ((__cpu_flags & X86_CPU_SSE2)==X86_CPU_SSE2)
+ {
+ gCpuCaps.hasSSE2=1;
+ }
+ mp_msg(MSGT_CPUDETECT,MSGL_V, gCpuCaps.hasSSE2 ? "yes.\n" : "no!\n" );
#else
/* Do nothing on other platforms for now.
*/
diff -u -r -N mplayer-export-2013-02-03-orig/libao2/ao_qsa.c
mplayer-export-2013-02-03/libao2/ao_qsa.c
--- mplayer-export-2013-02-03-orig/libao2/ao_qsa.c 1970-01-01
02:00:00.000000000 +0200
+++ mplayer-export-2013-02-03/libao2/ao_qsa.c 2013-01-26
19:28:55.000000000 +0200
@@ -0,0 +1,415 @@
+/*
+ * QSA (QNX Sound Architecture) audio output driver
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer 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.
+ *
+ * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sched.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <sys/neutrino.h>
+#include <sys/asoundlib.h>
+
+#include "mp_msg.h"
+#include "config.h"
+#include "libaf/af_format.h"
+#include "audio_out.h"
+#include "audio_out_internal.h"
+
+static const ao_info_t info =
+{
+ "QSA audio output",
+ "qsa",
+ "Mike Gorchak <mike.gorchak.qnx at gmail.com>",
+ ""
+};
+
+LIBAO_EXTERN(qsa)
+
+snd_pcm_channel_params_t cpars;
+snd_pcm_channel_setup_t csetup;
+snd_pcm_t* audio_handle=NULL;
+int audio_fd;
+
+static int control(int cmd, void* arg)
+{
+ switch(cmd)
+ {
+ case AOCONTROL_QUERY_FORMAT:
+ return CONTROL_TRUE;
+ case AOCONTROL_SET_DEVICE:
+ case AOCONTROL_GET_DEVICE:
+ case AOCONTROL_GET_VOLUME:
+ case AOCONTROL_SET_VOLUME:
+ case AOCONTROL_SET_PLUGIN_DRIVER:
+ case AOCONTROL_SET_PLUGIN_LIST:
+ default:
+ return CONTROL_UNKNOWN;
+ }
+
+ return CONTROL_UNKNOWN;
+}
+
+static int init(int rate, int channels, int format, int flags)
+{
+ int qsa_format=SND_PCM_SFMT_S16_LE;
+ int frag_multiplier=1;
+ int status;
+ int cardno;
+ int deviceno;
+ int try_again=0;
+
+ mp_msg(MSGT_AO, MSGL_V, "qsa-init: requested format: %d Hz, %d
channels, %x\n",
+ rate, channels, format);
+ mp_msg(MSGT_AO, MSGL_V, "qsa-init: compiled for QSA %s\n",
SND_LIB_VERSION_STR);
+
+ switch(format)
+ {
+ case AF_FORMAT_U8:
+ qsa_format=SND_PCM_SFMT_U8;
+ break;
+ case AF_FORMAT_S8:
+ qsa_format=SND_PCM_SFMT_S8;
+ break;
+ case AF_FORMAT_U16_LE:
+ qsa_format=SND_PCM_SFMT_U16_LE;
+ frag_multiplier=2;
+ break;
+ case AF_FORMAT_U16_BE:
+ qsa_format=SND_PCM_SFMT_U16_BE;
+ frag_multiplier=2;
+ break;
+ case AF_FORMAT_S16_LE:
+ qsa_format=SND_PCM_SFMT_S16_LE;
+ frag_multiplier=2;
+ break;
+ case AF_FORMAT_S16_BE:
+ qsa_format=SND_PCM_SFMT_S16_BE;
+ frag_multiplier=2;
+ break;
+ case AF_FORMAT_U24_LE:
+ qsa_format=SND_PCM_SFMT_U24_LE;
+ frag_multiplier=3;
+ break;
+ case AF_FORMAT_U24_BE:
+ qsa_format=SND_PCM_SFMT_U24_BE;
+ frag_multiplier=3;
+ break;
+ case AF_FORMAT_S24_LE:
+ qsa_format=SND_PCM_SFMT_S24_LE;
+ frag_multiplier=3;
+ break;
+ case AF_FORMAT_S24_BE:
+ qsa_format=SND_PCM_SFMT_S24_BE;
+ frag_multiplier=3;
+ break;
+ case AF_FORMAT_U32_LE:
+ qsa_format=SND_PCM_SFMT_U32_LE;
+ frag_multiplier=4;
+ break;
+ case AF_FORMAT_U32_BE:
+ qsa_format=SND_PCM_SFMT_U32_BE;
+ frag_multiplier=4;
+ break;
+ case AF_FORMAT_S32_LE:
+ qsa_format=SND_PCM_SFMT_S32_LE;
+ frag_multiplier=4;
+ break;
+ case AF_FORMAT_S32_BE:
+ qsa_format=SND_PCM_SFMT_S32_BE;
+ frag_multiplier=4;
+ break;
+ case AF_FORMAT_FLOAT_LE:
+ qsa_format=SND_PCM_SFMT_FLOAT_LE;
+ frag_multiplier=4;
+ break;
+ case AF_FORMAT_FLOAT_BE:
+ qsa_format=SND_PCM_SFMT_FLOAT_BE;
+ frag_multiplier=4;
+ break;
+ case AF_FORMAT_AC3_LE:
+ qsa_format=SND_PCM_SFMT_IEC958_SUBFRAME_LE;
+ frag_multiplier=2;
+ break;
+ case AF_FORMAT_AC3_BE:
+ qsa_format=SND_PCM_SFMT_IEC958_SUBFRAME_BE;
+ frag_multiplier=2;
+ break;
+ case AF_FORMAT_IEC61937_LE:
+ qsa_format=SND_PCM_SFMT_IEC958_SUBFRAME_LE;
+ frag_multiplier=2;
+ break;
+ case AF_FORMAT_IEC61937_BE:
+ qsa_format=SND_PCM_SFMT_IEC958_SUBFRAME_BE;
+ frag_multiplier=2;
+ break;
+ default:
+ qsa_format=SND_PCM_SFMT_S16_LE;
+ frag_multiplier=2;
+ break;
+ }
+
+ memset(&cpars, 0, sizeof(cpars));
+
+ cpars.channel=SND_PCM_CHANNEL_PLAYBACK;
+ cpars.mode=SND_PCM_MODE_BLOCK;
+ cpars.start_mode=SND_PCM_START_DATA;
+ cpars.stop_mode=SND_PCM_STOP_ROLLOVER;
+ cpars.format.format=qsa_format;
+ cpars.format.interleave=1;
+ cpars.format.rate=rate;
+ cpars.format.voices=channels;
+ cpars.buf.block.frag_size=2048*frag_multiplier*channels;
+ cpars.buf.block.frags_min=16;
+ cpars.buf.block.frags_max=32;
+
+ status=snd_pcm_open_preferred(&audio_handle, &cardno, &deviceno,
SND_PCM_OPEN_PLAYBACK);
+
+ /* Check if requested device is opened */
+ if (status<0)
+ {
+ mp_msg(MSGT_AO, MSGL_ERR, "qsa-init: can't open preferred device\n");
+ return 0;
+ }
+
+ /* Disable mmap to control data transfer to the audio device */
+ snd_pcm_plugin_set_disable(audio_handle, PLUGIN_DISABLE_MMAP);
+
+ /* Check if QSA and underlying driver can accept requested parameters */
+ status=snd_pcm_plugin_params(audio_handle, &cpars);
+ if (status<0)
+ {
+ do {
+ if ((format==AF_FORMAT_FLOAT_LE) && (try_again==0))
+ {
+ format=AF_FORMAT_S32_LE;
+ qsa_format=SND_PCM_SFMT_S32_LE;
+ cpars.buf.block.frag_size=8192*4;
+ try_again=1;
+ }
+ if ((format==AF_FORMAT_FLOAT_BE) && (try_again==0))
+ {
+ format=AF_FORMAT_S32_BE;
+ qsa_format=SND_PCM_SFMT_S32_BE;
+ cpars.buf.block.frag_size=8192*4;
+ try_again=1;
+ }
+ if ((format==AF_FORMAT_S32_LE) && (try_again==0))
+ {
+ format=AF_FORMAT_S16_LE;
+ qsa_format=SND_PCM_SFMT_S16_LE;
+ cpars.buf.block.frag_size=8192*2;
+ try_again=1;
+ }
+ if ((format==AF_FORMAT_S32_BE) && (try_again==0))
+ {
+ format=AF_FORMAT_S16_BE;
+ qsa_format=SND_PCM_SFMT_S16_BE;
+ cpars.buf.block.frag_size=8192*2;
+ try_again=1;
+ }
+ if ((channels>=6) && (try_again==0))
+ {
+ channels=4;
+ try_again=1;
+ }
+ if ((channels>=4) && (try_again==0))
+ {
+ channels=2;
+ try_again=1;
+ }
+ if ((channels>=2) && (try_again==0))
+ {
+ channels=1;
+ try_again=1;
+ }
+ if ((rate>=192000) && (try_again==0))
+ {
+ rate=96000;
+ try_again=1;
+ }
+ if ((rate>=96000) && (try_again==0))
+ {
+ rate=48000;
+ try_again=1;
+ }
+ if ((rate>=48000) && (try_again==0))
+ {
+ rate=44100;
+ try_again=1;
+ }
+ if (try_again)
+ {
+ cpars.format.format=qsa_format;
+ cpars.format.voices=channels;
+ cpars.format.rate=rate;
+ status=snd_pcm_plugin_params(audio_handle, &cpars);
+ if (status<0)
+ {
+ continue;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ mp_msg(MSGT_AO, MSGL_ERR, "qsa-init: can't find
compatible sample format\n");
+ return 0;
+ }
+ } while(1);
+ }
+
+ memset(&csetup, 0x00, sizeof(csetup));
+ csetup.channel=SND_PCM_CHANNEL_PLAYBACK;
+
+ status=snd_pcm_plugin_setup(audio_handle, &csetup);
+ if (status<0)
+ {
+ mp_msg(MSGT_AO, MSGL_ERR, "qsa-init: can't setup playback channel\n");
+ return 0;
+ }
+
+ ao_data.samplerate=rate;
+ ao_data.format=format;
+ ao_data.channels=channels;
+ ao_data.bps=(af_fmt2bits(ao_data.format)/8)*ao_data.channels*ao_data.samplerate;
+ ao_data.buffersize=csetup.buf.block.frag_size*csetup.buf.block.frags;
+
+ audio_fd=snd_pcm_file_descriptor(audio_handle, SND_PCM_CHANNEL_PLAYBACK);
+ if (audio_fd<0)
+ {
+ mp_msg(MSGT_AO, MSGL_ERR, "qsa-init: can't get handle of
playback channel\n");
+ return 0;
+ }
+
+ status=snd_pcm_plugin_prepare(audio_handle, SND_PCM_CHANNEL_PLAYBACK);
+ if (status<0)
+ {
+ mp_msg(MSGT_AO, MSGL_ERR, "qsa-init: can't get prepare
playback channel\n");
+ return 0;
+ }
+
+ mp_msg(MSGT_AO, MSGL_V, "qsa-init: used format: %d Hz, %d channels, %x\n",
+ rate, channels, format);
+
+ return 1;
+}
+
+static void uninit(int immed)
+{
+ snd_pcm_playback_flush(audio_handle);
+ snd_pcm_close(audio_handle);
+}
+
+static void drain(void)
+{
+ snd_pcm_plugin_playback_drain(audio_handle);
+}
+
+static void reset(void)
+{
+ snd_pcm_plugin_playback_drain(audio_handle);
+ snd_pcm_plugin_prepare(audio_handle, SND_PCM_CHANNEL_PLAYBACK);
+}
+
+static void audio_pause(void)
+{
+ snd_pcm_playback_pause(audio_handle);
+}
+
+static void audio_resume(void)
+{
+ snd_pcm_playback_resume(audio_handle);
+}
+
+static int get_space(void)
+{
+ int status;
+ snd_pcm_channel_status_t cstatus;
+
+ memset(&cstatus, 0, sizeof(cstatus));
+ cstatus.channel=SND_PCM_CHANNEL_PLAYBACK;
+
+ status=snd_pcm_plugin_status(audio_handle, &cstatus);
+ if (status<0)
+ {
+ return 0;
+ }
+
+ return cstatus.free;
+}
+
+static int play(void* data, int len, int flags)
+{
+ int written;
+ int status;
+ snd_pcm_channel_status_t cstatus;
+
+ written=snd_pcm_plugin_write(audio_handle, data, len);
+ if (written!=len)
+ {
+ /* Check if samples playback got stuck somewhere in hardware or in */
+ /* the audio device driver */
+ if ((errno==EAGAIN) && (written==0))
+ {
+ return 0;
+ }
+ if ((errno==EINVAL) || (errno==EIO))
+ {
+ memset(&cstatus, 0, sizeof(cstatus));
+ cstatus.channel=SND_PCM_CHANNEL_PLAYBACK;
+ status=snd_pcm_plugin_status(audio_handle, &cstatus);
+ if (status>0)
+ {
+ return 0;
+ }
+ if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) ||
+ (cstatus.status == SND_PCM_STATUS_READY))
+ {
+ status=snd_pcm_plugin_prepare(audio_handle,
SND_PCM_CHANNEL_PLAYBACK);
+ if (status<0)
+ {
+ return 0;
+ }
+ }
+ }
+ }
+
+ return written;
+}
+
+static float get_delay(void)
+{
+ int status;
+ snd_pcm_channel_status_t cstatus;
+
+ memset(&cstatus, 0, sizeof(cstatus));
+ cstatus.channel=SND_PCM_CHANNEL_PLAYBACK;
+
+ status=snd_pcm_plugin_status(audio_handle, &cstatus);
+ if (status<0)
+ {
+ return (float)ao_data.buffersize/(float)ao_data.bps;
+ }
+
+ return (float)cstatus.count/(float)ao_data.bps;
+}
diff -u -r -N mplayer-export-2013-02-03-orig/libao2/audio_out.c
mplayer-export-2013-02-03/libao2/audio_out.c
--- mplayer-export-2013-02-03-orig/libao2/audio_out.c 2013-01-31
07:24:06.000000000 +0200
+++ mplayer-export-2013-02-03/libao2/audio_out.c 2013-02-03
15:01:58.000000000 +0200
@@ -40,6 +40,7 @@
extern const ao_functions_t audio_out_openal;
extern const ao_functions_t audio_out_null;
extern const ao_functions_t audio_out_alsa;
+extern const ao_functions_t audio_out_qsa;
extern const ao_functions_t audio_out_nas;
extern const ao_functions_t audio_out_sdl;
extern const ao_functions_t audio_out_sun;
@@ -85,6 +86,9 @@
#ifdef CONFIG_SUN_AUDIO
&audio_out_sun,
#endif
+#ifdef CONFIG_QSA
+ &audio_out_qsa,
+#endif
// wrappers:
#ifdef CONFIG_ARTS
&audio_out_arts,
diff -u -r -N mplayer-export-2013-02-03-orig/libdvdread4/bswap.h
mplayer-export-2013-02-03/libdvdread4/bswap.h
--- mplayer-export-2013-02-03-orig/libdvdread4/bswap.h 2013-01-31
07:24:56.000000000 +0200
+++ mplayer-export-2013-02-03/libdvdread4/bswap.h 2013-02-03
15:03:30.000000000 +0200
@@ -92,6 +92,12 @@
(((x) & 0x000000000000ff00ULL) << 40) | \
(((x) & 0x00000000000000ffULL) << 56))
+#elif defined(__QNXNTO__)
+#include <gulliver.h>
+#define B2N_16(x) x = ENDIAN_SWAP16(x)
+#define B2N_32(x) x = ENDIAN_SWAP32(x)
+#define B2N_64(x) x = ENDIAN_SWAP64(x)
+
#else
/* If there isn't a header provided with your system with this functionality
diff -u -r -N mplayer-export-2013-02-03-orig/libmpcodecs/vf_pp7.c
mplayer-export-2013-02-03/libmpcodecs/vf_pp7.c
--- mplayer-export-2013-02-03-orig/libmpcodecs/vf_pp7.c 2013-01-31
07:24:01.000000000 +0200
+++ mplayer-export-2013-02-03/libmpcodecs/vf_pp7.c 2013-02-03
15:13:00.000000000 +0200
@@ -44,7 +44,9 @@
#define XMIN(a,b) ((a) < (b) ? (a) : (b))
#define XMAX(a,b) ((a) > (b) ? (a) : (b))
+#if !defined(__QNXNTO__)
typedef short int16_t;
+#endif /* __QNXNTO__ */
//===========================================================================//
static const uint8_t __attribute__((aligned(8))) dither[8][8]={
diff -u -r -N mplayer-export-2013-02-03-orig/libvo/video_out.c
mplayer-export-2013-02-03/libvo/video_out.c
--- mplayer-export-2013-02-03-orig/libvo/video_out.c 2013-01-31
07:24:16.000000000 +0200
+++ mplayer-export-2013-02-03/libvo/video_out.c 2013-02-03
15:04:44.000000000 +0200
@@ -136,6 +136,7 @@
extern const vo_functions_t video_out_pnm;
extern const vo_functions_t video_out_md5sum;
extern const vo_functions_t video_out_mng;
+extern const vo_functions_t video_out_photon;
/* The following declarations are _not_ const because functions pointers
* get overloaded during (re)initialization. */
@@ -254,6 +255,9 @@
#ifdef CONFIG_VESA
&video_out_vesa,
#endif
+#ifdef CONFIG_PHOTON
+ &video_out_photon,
+#endif
#ifdef CONFIG_DIRECTFB
&video_out_directfb,
&video_out_dfbmga,
diff -u -r -N mplayer-export-2013-02-03-orig/libvo/vo_photon.c
mplayer-export-2013-02-03/libvo/vo_photon.c
--- mplayer-export-2013-02-03-orig/libvo/vo_photon.c 1970-01-01
02:00:00.000000000 +0200
+++ mplayer-export-2013-02-03/libvo/vo_photon.c 2013-02-03
18:44:25.000000000 +0200
@@ -0,0 +1,1460 @@
+/*
+ * Copyright (C) 2013 Mike Gorchak <mike.gorchak.qnx at gmail.com>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer 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.
+ *
+ * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <Ph.h>
+#include <Pt.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "mp_fifo.h"
+#include "help_mp.h"
+#include "aspect.h"
+#include "sub/sub.h"
+#include "fastmemcpy.h"
+#include "osdep/keycodes.h"
+#include "input/input.h"
+#include "input/mouse.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+
+static const vo_info_t info =
+{
+ "Photon YUV/BGR renderer",
+ "photon",
+ "Mike Gorchak <mike.gorchak.qnx at gmail.com>",
+ ""
+};
+
+const LIBVO_EXTERN(photon)
+
+int phwindow_ontop=VO_FALSE;
+int phwindow_fullscreen=VO_FALSE;
+int phwindow_fullscreen_set=VO_TRUE;
+
+int phinited=0;
+PtWidget_t* phwindow=NULL;
+PtWidget_t* phoscontainer=NULL;
+PtWidget_t* phrawcontainer=NULL;
+
+#define PHW_WINDOW_CHANGE_POSITION 0x00000001
+#define PHW_WINDOW_CHANGE_SIZE 0x00000002
+#define PHW_WINDOW_EXIT_REQUESTED 0x00000004
+#define PHW_WINDOW_MAXIMIZE_EVENT 0x00000008
+
+unsigned int phwindow_event_flags;
+PhDim_t phwindow_dimension;
+PhDim_t phwindow_old_dimension;
+PhPoint_t phwindow_position;
+PhPoint_t phwindow_old_position;
+PhDim_t phwindow_fs_dimension;
+PhPoint_t phwindow_fs_position;
+
+unsigned long photon_display_format;
+int photon_mplayer_format;
+int photon_format_idx=0;
+int photon_screen_width;
+int photon_screen_height;
+int photon_video_width;
+int photon_video_height;
+int photon_target_video_pos_x;
+int photon_target_video_pos_y;
+int photon_target_video_width;
+int photon_target_video_height;
+int photon_source_video_pos_x;
+int photon_source_video_pos_y;
+int photon_source_video_width;
+int photon_source_video_height;
+
+#define PHRENDER_USE_NONE -1
+#define PHRENDER_USE_LAYER 0
+#define PHRENDER_USE_OFFSCREEN 1
+#define PHRENDER_USE_SWOFFSCREEN 2
+
+int phrender_type=PHRENDER_USE_NONE;
+int ph_image_current=0;
+PdOffscreenContext_t* ph_image_off=NULL;
+PdOffscreenContext_t* ph_image_off2=NULL;
+void* ph_surface_data=NULL;
+void* ph_surface_data2=NULL;
+int ph_surface_width;
+int ph_surface_height;
+int ph_surface_pitch;
+PhPoint_t ph_position;
+PhRect_t ph_src_rect;
+PhRect_t ph_dst_rect;
+unsigned long ph_chroma_color;
+
+static void photon_configure_layer(void);
+
+static int draw_slice(uint8_t *image[], int stride[], int w, int h,
int x, int y)
+{
+ /* YV12 interface is not supported */
+ return -1;
+}
+
+static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
+ unsigned char *srca, int stride)
+{
+ switch (photon_mplayer_format)
+ {
+ case IMGFMT_YUY2:
+ case IMGFMT_YVYU:
+ if (ph_image_current==0)
+ {
+ vo_draw_alpha_yuy2(w, h, src, srca, stride,
((uint8_t *)ph_surface_data) +
+ ph_surface_pitch * y0 + 2 * x0, ph_surface_pitch);
+ }
+ else
+ {
+ vo_draw_alpha_yuy2(w, h, src, srca, stride,
((uint8_t *)ph_surface_data2) +
+ ph_surface_pitch * y0 + 2 * x0, ph_surface_pitch);
+ }
+ break;
+ case IMGFMT_UYVY:
+ case IMGFMT_V422:
+ if (ph_image_current==0)
+ {
+ vo_draw_alpha_uyvy(w, h, src, srca, stride,
((uint8_t *)ph_surface_data) +
+ ph_surface_pitch * y0 + 2 * x0, ph_surface_pitch);
+ }
+ else
+ {
+ vo_draw_alpha_uyvy(w, h, src, srca, stride,
((uint8_t *)ph_surface_data2) +
+ ph_surface_pitch * y0 + 2 * x0, ph_surface_pitch);
+ }
+ break;
+ case IMGFMT_BGR15:
+ if (ph_image_current==0)
+ {
+ vo_draw_alpha_rgb15(w, h, src, srca, stride,
((uint8_t *)ph_surface_data) +
+ ph_surface_pitch * y0 + 2 * x0, ph_surface_pitch);
+ }
+ else
+ {
+ vo_draw_alpha_rgb15(w, h, src, srca, stride,
((uint8_t *)ph_surface_data2) +
+ ph_surface_pitch * y0 + 2 * x0, ph_surface_pitch);
+ }
+ break;
+ case IMGFMT_BGR16:
+ if (ph_image_current==0)
+ {
+ vo_draw_alpha_rgb16(w, h, src, srca, stride,
((uint8_t *)ph_surface_data) +
+ ph_surface_pitch * y0 + 2 * x0, ph_surface_pitch);
+ }
+ else
+ {
+ vo_draw_alpha_rgb16(w, h, src, srca, stride,
((uint8_t *)ph_surface_data2) +
+ ph_surface_pitch * y0 + 2 * x0, ph_surface_pitch);
+ }
+ break;
+ case IMGFMT_BGR24:
+ if (ph_image_current==0)
+ {
+ vo_draw_alpha_rgb24(w, h, src, srca, stride,
((uint8_t *)ph_surface_data) +
+ ph_surface_pitch * y0 + 4 * x0, ph_surface_pitch);
+ }
+ else
+ {
+ vo_draw_alpha_rgb24(w, h, src, srca, stride,
((uint8_t *)ph_surface_data2) +
+ ph_surface_pitch * y0 + 4 * x0, ph_surface_pitch);
+ }
+ break;
+ case IMGFMT_BGR32:
+ if (ph_image_current==0)
+ {
+ vo_draw_alpha_rgb32(w, h, src, srca, stride,
((uint8_t *)ph_surface_data) +
+ ph_surface_pitch * y0 + 4 * x0, ph_surface_pitch);
+ }
+ else
+ {
+ vo_draw_alpha_rgb32(w, h, src, srca, stride,
((uint8_t *)ph_surface_data2) +
+ ph_surface_pitch * y0 + 4 * x0, ph_surface_pitch);
+ }
+ break;
+ }
+}
+
+static void draw_osd(void)
+{
+ vo_draw_text(photon_video_width, photon_video_height, draw_alpha);
+}
+
+static void ph_raw_draw_image(PtWidget_t* widget, PhTile_t* damage)
+{
+ PhRect_t ph_window_rect;
+
+ ph_window_rect.ul.x=0;
+ ph_window_rect.ul.y=0;
+ ph_window_rect.lr.x=vo_dwidth-1;
+ ph_window_rect.lr.y=vo_dheight-1;
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ PgSetFillColor(ph_chroma_color);
+ }
+ else
+ {
+ PgSetFillColor(PgRGB(0x00, 0x00, 0x00));
+ }
+ PgDrawRect(&ph_window_rect, Pg_DRAW_FILL);
+
+ if (phrender_type!=PHRENDER_USE_LAYER)
+ {
+ PgContextBlit(ph_image_off, &ph_src_rect, PhDCGetCurrent(),
&ph_dst_rect);
+ if (vo_vsync)
+ {
+ PgWaitVSync();
+ }
+ PgFlush();
+ }
+}
+
+static void flip_page(void)
+{
+ switch (phrender_type)
+ {
+ case PHRENDER_USE_OFFSCREEN:
+ case PHRENDER_USE_SWOFFSCREEN:
+ {
+ PtDamageWidget(phrawcontainer);
+ PtFlush();
+ }
+ break;
+ case PHRENDER_USE_LAYER:
+ {
+ ph_image_current=!ph_image_current;
+ photon_configure_layer();
+ PtDamageWidget(phrawcontainer);
+ PtFlush();
+ PgWaitVSync();
+ }
+ break;
+ }
+}
+
+static int draw_frame(uint8_t *src[])
+{
+ /* Old interface is not supported */
+ return -1;
+}
+
+typedef struct _layer_mp_map
+{
+ unsigned int layer_id;
+ unsigned int mp_id;
+ unsigned int format_idx;
+ unsigned int found;
+} layer_mp_map_t;
+
+layer_mp_map_t photon_layer_map[]=
+{
+ {Pg_LAYER_FORMAT_ARGB1555, IMGFMT_BGR15, 0, 0},
+ {Pg_LAYER_FORMAT_RGB565, IMGFMT_BGR16, 0, 0},
+ {Pg_LAYER_FORMAT_RGB888, IMGFMT_BGR24, 0, 0},
+ {Pg_LAYER_FORMAT_ARGB8888, IMGFMT_BGR32, 0, 0},
+ {Pg_LAYER_FORMAT_YUY2, IMGFMT_YUY2, 0, 0},
+ {Pg_LAYER_FORMAT_YUY2, IMGFMT_YUNV, 0, 0},
+ {Pg_LAYER_FORMAT_UYVY, IMGFMT_UYVY, 0, 0},
+ {Pg_LAYER_FORMAT_UYVY, IMGFMT_UYNV, 0, 0},
+ {Pg_LAYER_FORMAT_YVYU, IMGFMT_YVYU, 0, 0},
+ {Pg_LAYER_FORMAT_V422, IMGFMT_V422, 0, 0},
+ {0, 0, 0, 0},
+};
+
+static int query_format(uint32_t format)
+{
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ int it=0;
+
+ do {
+ if ((photon_layer_map[it].layer_id==0) &&
(photon_layer_map[it].mp_id==0))
+ {
+ return 0;
+ }
+ if ((photon_layer_map[it].mp_id==format) &&
(photon_layer_map[it].found))
+ {
+ return VFCAP_CSP_SUPPORTED |
VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
+ VFCAP_ACCEPT_STRIDE | VFCAP_FLIP | VFCAP_HWSCALE_UP |
+ VFCAP_HWSCALE_DOWN | VOCAP_NOSLICES |
VFCAP_EOSD | VFCAP_EOSD_UNSCALED;
+ }
+ it++;
+ } while(1);
+ }
+ else
+ {
+ switch(format)
+ {
+ case IMGFMT_BGR15:
+ case IMGFMT_BGR16:
+ case IMGFMT_BGR24:
+ case IMGFMT_BGR32:
+ if (((photon_display_format==Pg_IMAGE_DIRECT_565) &&
(format==IMGFMT_BGR16)) ||
+ ((photon_display_format==Pg_IMAGE_DIRECT_1555)
&& (format==IMGFMT_BGR15)) ||
+ ((photon_display_format==Pg_IMAGE_DIRECT_888) &&
(format==IMGFMT_BGR24)) ||
+ ((photon_display_format==Pg_IMAGE_DIRECT_8888)
&& (format==IMGFMT_BGR32)))
+ {
+ return VFCAP_CSP_SUPPORTED |
VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
+ VFCAP_ACCEPT_STRIDE | VFCAP_FLIP |
VFCAP_SWSCALE | VFCAP_HWSCALE_UP |
+ VFCAP_HWSCALE_DOWN | VOCAP_NOSLICES |
VFCAP_EOSD | VFCAP_EOSD_UNSCALED;
+ }
+ else
+ {
+ return VFCAP_CSP_SUPPORTED | VFCAP_OSD |
VFCAP_ACCEPT_STRIDE | VFCAP_FLIP |
+ VFCAP_SWSCALE | VOCAP_NOSLICES |
VFCAP_EOSD | VFCAP_EOSD_UNSCALED;
+
+ }
+ }
+
+ return 0;
+ }
+}
+
+typedef struct _photon_mp_keydef
+{
+ int photon_key;
+ int mp_key;
+} photon_mp_keydef_t;
+
+photon_mp_keydef_t photon_keymap[]=
+{
+ {Pk_Tab, KEY_TAB },
+ {Pk_Return, KEY_ENTER },
+ {Pk_BackSpace, KEY_BACKSPACE},
+ {Pk_Delete, KEY_DELETE },
+ {Pk_Insert, KEY_INSERT },
+ {Pk_Home, KEY_HOME },
+ {Pk_End, KEY_END },
+ {Pk_Pg_Up, KEY_PAGE_UP },
+ {Pk_Pg_Down, KEY_PAGE_DOWN},
+ {Pk_Escape, KEY_ESC },
+ {Pk_Right, KEY_RIGHT },
+ {Pk_Left, KEY_LEFT },
+ {Pk_Down, KEY_DOWN },
+ {Pk_Up, KEY_UP },
+ {Pk_Control_L, KEY_CTRL },
+ {Pk_Control_R, KEY_CTRL },
+ {Pk_F1, KEY_F+1 },
+ {Pk_F2, KEY_F+2 },
+ {Pk_F3, KEY_F+3 },
+ {Pk_F4, KEY_F+4 },
+ {Pk_F5, KEY_F+5 },
+ {Pk_F6, KEY_F+6 },
+ {Pk_F7, KEY_F+7 },
+ {Pk_F8, KEY_F+8 },
+ {Pk_F9, KEY_F+9 },
+ {Pk_F10, KEY_F+10 },
+ {Pk_F11, KEY_F+11 },
+ {Pk_F12, KEY_F+12 },
+ {Pk_KP_0, KEY_KP0 },
+ {Pk_KP_1, KEY_KP1 },
+ {Pk_KP_2, KEY_KP2 },
+ {Pk_KP_3, KEY_KP3 },
+ {Pk_KP_4, KEY_KP4 },
+ {Pk_KP_5, KEY_KP5 },
+ {Pk_KP_6, KEY_KP6 },
+ {Pk_KP_7, KEY_KP7 },
+ {Pk_KP_8, KEY_KP8 },
+ {Pk_KP_9, KEY_KP9 },
+ {Pk_KP_Enter, KEY_KPENTER },
+ {0, 0 },
+};
+
+static int phwindow_callback(PtWidget_t* widget, void* data,
PtCallbackInfo_t* info)
+{
+ switch (info->event->type)
+ {
+ case Ph_EV_KEY:
+ {
+ PhKeyEvent_t* keyevent=NULL;
+
+ keyevent=PhGetData(info->event);
+ if (keyevent==NULL)
+ {
+ break;
+ }
+
+ /* Check if key has been translated to the symbol */
+ if ((keyevent->key_flags & Pk_KF_Sym_Valid)==Pk_KF_Sym_Valid)
+ {
+ int it=0;
+ int found=0;
+
+ do {
+ if ((photon_keymap[it].photon_key==0) &&
(photon_keymap[it].mp_key==0))
+ {
+ break;
+ }
+ if (photon_keymap[it].photon_key==keyevent->key_sym)
+ {
+ mplayer_put_key(photon_keymap[it].mp_key);
+ found=1;
+ break;
+ }
+ it++;
+ } while(1);
+ if (!found)
+ {
+ if (keyevent->key_sym<0x0100)
+ {
+ mplayer_put_key(keyevent->key_sym);
+ }
+ }
+ }
+ }
+ break;
+ case Ph_EV_BUT_PRESS:
+ {
+ PhPointerEvent_t* ptrevent=NULL;
+
+ ptrevent=PhGetData(info->event);
+ if (ptrevent==NULL)
+ {
+ break;
+ }
+
+ if (ptrevent->buttons & Ph_BUTTON_SELECT)
+ {
+ mplayer_put_key(MOUSE_BTN0 | MP_KEY_DOWN);
+ }
+
+ if (ptrevent->buttons & Ph_BUTTON_MENU)
+ {
+ mplayer_put_key(MOUSE_BTN1 | MP_KEY_DOWN);
+ }
+
+ if (ptrevent->buttons & Ph_BUTTON_ADJUST)
+ {
+ mplayer_put_key(MOUSE_BTN2 | MP_KEY_DOWN);
+ }
+ }
+ break;
+ case Ph_EV_BUT_RELEASE:
+ {
+ PhPointerEvent_t* ptrevent=NULL;
+
+ ptrevent=PhGetData(info->event);
+ if (ptrevent==NULL)
+ {
+ break;
+ }
+
+ if (ptrevent->buttons & Ph_BUTTON_SELECT)
+ {
+ mplayer_put_key(MOUSE_BTN0);
+ }
+
+ if (ptrevent->buttons & Ph_BUTTON_MENU)
+ {
+ mplayer_put_key(MOUSE_BTN1);
+ }
+
+ if (ptrevent->buttons & Ph_BUTTON_ADJUST)
+ {
+ mplayer_put_key(MOUSE_BTN2);
+ }
+ }
+ break;
+ case Ph_EV_PTR_MOTION_BUTTON:
+ case Ph_EV_PTR_MOTION_NOBUTTON:
+ {
+ PhPointerEvent_t* ptrevent=NULL;
+ short x;
+ short y;
+
+ ptrevent=PhGetData(info->event);
+ if (ptrevent==NULL)
+ {
+ break;
+ }
+
+ PtGetAbsPosition(phrawcontainer, &x, &y);
+ x=ptrevent->pos.x-x;
+ y=ptrevent->pos.y-y;
+
+ vo_mouse_movement(x, y);
+ }
+ break;
+ }
+
+ return Pt_CONTINUE;
+}
+
+static void photon_configure_layer(void)
+{
+ PhArea_t source_viewport;
+ PhArea_t destination_viewport;
+ PgChroma_t chroma_key;
+ short x;
+ short y;
+ int active=1;
+ unsigned int filter=Pg_LAYER_FILTER;
+ PhRect_t workspace_rect;
+
+ PhWindowQueryVisible(Ph_QUERY_WORKSPACE, 0, PhInputGroup(NULL),
&workspace_rect);
+ PtGetAbsPosition(phrawcontainer, &x , &y);
+ x-=workspace_rect.ul.x;
+ y-=workspace_rect.ul.y;
+
+ PgSetLayerArg(1, Pg_LAYER_ARG_LIST_BEGIN, 0, 0);
+ PgSetLayerArg(1, Pg_LAYER_ARG_FORMAT_INDEX, &photon_format_idx,
sizeof(int));
+ if (ph_image_current==0)
+ {
+ PgSetLayerSurface(1, 0, ph_image_off2);
+ }
+ else
+ {
+ PgSetLayerSurface(1, 0, ph_image_off);
+ }
+ chroma_key.op=Pg_CHROMA_DEST_MATCH | Pg_CHROMA_DRAW | Pg_ENABLE_CHROMA;
+ chroma_key.color=ph_chroma_color;
+ PgSetLayerArg(1, Pg_LAYER_ARG_CHROMA, &chroma_key, sizeof(chroma_key));
+ PgSetLayerArg(1, Pg_LAYER_ARG_FILTER_MODE, &filter, sizeof(filter));
+ PgSetLayerArg(1, Pg_LAYER_ARG_ACTIVE, &active, sizeof(active));
+ source_viewport.pos.x=ph_src_rect.ul.x;
+ source_viewport.pos.y=ph_src_rect.ul.y;
+ source_viewport.size.w=(ph_src_rect.lr.x-ph_src_rect.ul.x+1);
+ source_viewport.size.h=(ph_src_rect.lr.y-ph_src_rect.ul.y+1);
+ PgSetLayerArg(1, Pg_LAYER_ARG_SRC_VIEWPORT, &source_viewport,
sizeof(source_viewport));
+ destination_viewport.pos.x=ph_dst_rect.ul.x+x;
+ destination_viewport.pos.y=ph_dst_rect.ul.y+y;
+ destination_viewport.size.w=ph_dst_rect.lr.x-ph_dst_rect.ul.x+1;
+ destination_viewport.size.h=ph_dst_rect.lr.y-ph_dst_rect.ul.y+1;
+ PgSetLayerArg(1, Pg_LAYER_ARG_DST_VIEWPORT,
&destination_viewport, sizeof(destination_viewport));
+ PgSetLayerArg(1, Pg_LAYER_ARG_LIST_END, 0, 0);
+}
+
+static int create_window(char* title, int width, int height)
+{
+ PtArg_t winargs[64];
+ uint32_t winargc=0;
+ int32_t status;
+ PhDim_t temp_dim={width, height};
+ PhDim_t temp_dim2={128, 64};
+ PhPoint_t temp_pos={vo_dx, vo_dy};
+ PtRawCallback_t raw_cb;
+
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_TITLE, title, strlen(title));
+ PtSetArg(&winargs[winargc++], Pt_ARG_BASIC_FLAGS, Pt_TRUE,
Pt_BASIC_PREVENT_FILL);
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE,
+ Ph_WM_APP_DEF_MANAGED | Ph_WM_RESIZE | Ph_WM_CLOSE);
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE,
+ Ph_WM_BACKDROP | Ph_WM_TOFRONT | Ph_WM_COLLAPSE | Ph_WM_FFRONT |
+ Ph_WM_HELP | Ph_WM_HIDE | Ph_WM_MOVE |
+ Ph_WM_MENU | Ph_WM_RESTORE | Ph_WM_TASKBAR |
+ Ph_WM_TOBACK | Ph_WM_MAX | Ph_WM_FOCUS);
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE,
+ Ph_WM_HELP);
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE,
+ Ph_WM_COLLAPSE | Ph_WM_FOCUS | Ph_WM_MAX | Ph_WM_CLOSE |
+ Ph_WM_MOVE | Ph_WM_RESIZE | Ph_WM_RESTORE | Ph_WM_HIDE);
+ if (vo_border)
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE,
+ Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN |
+ Ph_WM_RENDER_TITLE | Ph_WM_RENDER_MOVE | Ph_WM_RENDER_ASAPP |
+ Ph_WM_RENDER_MAX | Ph_WM_RENDER_BORDER);
+ }
+ else
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE,
+ Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN |
+ Ph_WM_RENDER_TITLE | Ph_WM_RENDER_MOVE | Ph_WM_RENDER_ASAPP |
+ Ph_WM_RENDER_MAX);
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE,
+ Ph_WM_RENDER_BORDER);
+ }
+ if ((vo_dx!=INT_MAX) && (vo_dy!=INT_MAX))
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_POS, &temp_pos, 0);
+ }
+ PtSetArg(&winargs[winargc++], Pt_ARG_DIM, &temp_dim, 0);
+ PtSetArg(&winargs[winargc++], Pt_ARG_MINIMUM_DIM, &temp_dim2, 0);
+
+ raw_cb.event_mask=Ph_EV_KEY;
+ raw_cb.event_f=phwindow_callback;
+ raw_cb.data=(void*)NULL;
+ PtSetArg(&winargs[winargc++], Pt_CB_RAW, &raw_cb, 0);
+
+ if (vo_ontop)
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE,
Ph_WM_STATE_ISFRONT);
+ }
+ else
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_WINDOW_STATE, Pt_FALSE,
Ph_WM_STATE_ISFRONT);
+ }
+
+ /* Finally create the window */
+ phwindow=PtCreateWidget(PtWindow, Pt_NO_PARENT, winargc, winargs);
+ if (phwindow==NULL)
+ {
+ return -1;
+ }
+
+ /* Create PtOSContainer widget for flicker-free updating */
+ winargc=0;
+ PtSetArg(&winargs[winargc++], Pt_ARG_DIM, &temp_dim, 0);
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_FILL_COLOR, ph_chroma_color, 0);
+ }
+ else
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_FILL_COLOR, PgRGB(0x00,
0x00, 0x00), 0);
+ }
+
+ /* Create the PtOSContainer widget */
+ phoscontainer=PtCreateWidget(PtOSContainer, phwindow, winargc, winargs);
+ if (phoscontainer==NULL)
+ {
+ return -1;
+ }
+
+ /* Create PtRaw widget as main container */
+ winargc=0;
+ PtSetArg(&winargs[winargc++], Pt_ARG_DIM, &temp_dim, 0);
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_FILL_COLOR, ph_chroma_color, 0);
+ }
+ else
+ {
+ PtSetArg(&winargs[winargc++], Pt_ARG_FILL_COLOR, PgRGB(0x00,
0x00, 0x00), 0);
+ }
+ PtSetArg(&winargs[winargc++], Pt_ARG_RAW_DRAW_F, ph_raw_draw_image, 0);
+
+ /* Create the PtRaw widget */
+ phrawcontainer=PtCreateWidget(PtRaw, phoscontainer, winargc, winargs);
+ if (phrawcontainer==NULL)
+ {
+ return -1;
+ }
+
+ /* Show widget */
+ status=PtRealizeWidget(phwindow);
+ if (status!=0)
+ {
+ PtDestroyWidget(phwindow);
+ }
+
+ /* Flush all widget operations */
+ PtFlush();
+}
+
+static int config(uint32_t width, uint32_t height, uint32_t d_width,
uint32_t d_height, uint32_t flags, char* title, uint32_t format)
+{
+ PhRect_t workspace_rect;
+
+ panscan_init();
+
+ /* Update window size */
+ phwindow_event_flags|=PHW_WINDOW_CHANGE_SIZE;
+
+ vo_dwidth=d_width;
+ vo_dheight=d_height;
+ phwindow_dimension.w=d_width;
+ phwindow_dimension.h=d_height;
+ phwindow_position.x=vo_dx;
+ phwindow_position.y=vo_dy;
+ photon_video_width=width;
+ photon_video_height=height;
+ photon_mplayer_format=format;
+
+ aspect_save_orig(width, height);
+ aspect_save_prescale(d_width, d_height);
+ aspect_save_screenres(vo_screenwidth, vo_screenheight);
+ geometry(&vo_dx, &vo_dy, &vo_dwidth, &vo_dheight, vo_screenwidth,
vo_screenheight);
+
+ /* Make sure our window will not be larger than a desktop resolution */
+ PhWindowQueryVisible(Ph_QUERY_WORKSPACE, 0, PhInputGroup(NULL),
&workspace_rect);
+ if (vo_dwidth>(workspace_rect.lr.x-workspace_rect.ul.x))
+ {
+ vo_dx=workspace_rect.ul.x;
+ vo_dy=workspace_rect.ul.y;
+ vo_dwidth=(workspace_rect.lr.x-workspace_rect.ul.x)-12;
+ }
+ if (vo_dheight>(workspace_rect.lr.y-workspace_rect.ul.y))
+ {
+ vo_dx=workspace_rect.ul.x;
+ vo_dy=workspace_rect.ul.y;
+ vo_dheight=(workspace_rect.lr.y-workspace_rect.ul.y)-12;
+ }
+
+ phwindow_dimension.w=vo_dwidth;
+ phwindow_dimension.h=vo_dheight;
+ phwindow_position.x=vo_dx;
+ phwindow_position.y=vo_dy;
+
+ if (vo_wintitle)
+ {
+ title=vo_wintitle;
+ }
+
+ create_window(title, vo_dwidth, vo_dheight);
+
+ photon_target_video_pos_x=0;
+ photon_target_video_pos_y=0;
+ photon_target_video_width=vo_dwidth;
+ photon_target_video_height=vo_dheight;
+
+ if ((flags & VOFLAG_FULLSCREEN)==VOFLAG_FULLSCREEN)
+ {
+ if (phwindow_fullscreen==VO_TRUE)
+ {
+ phwindow_fullscreen=VO_FALSE;
+ }
+ else
+ {
+ phwindow_fullscreen=VO_TRUE;
+ }
+ phwindow_fullscreen_set=VO_FALSE;
+ }
+
+ /* Try to use a direct layer renderer */
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ int it;
+
+ it=0;
+ do {
+ if ((photon_layer_map[it].layer_id==0) &&
(photon_layer_map[it].mp_id==0))
+ {
+ return 0;
+ }
+ if ((photon_layer_map[it].mp_id==format) &&
(photon_layer_map[it].found))
+ {
+ photon_format_idx=photon_layer_map[it].format_idx;
+ break;
+ }
+ it++;
+ } while(1);
+
+ ph_image_off=PgCreateLayerSurface(1, 0, photon_format_idx,
width, height, Pg_OSC_MEM_PAGE_ALIGN);
+ if (ph_image_off!=NULL)
+ {
+ ph_surface_data=PdGetOffscreenContextPtr(ph_image_off);
+ ph_surface_width=ph_image_off->dim.w;
+ ph_surface_height=ph_image_off->dim.h;
+ ph_surface_pitch=ph_image_off->pitch;
+ }
+ else
+ {
+ phrender_type=PHRENDER_USE_NONE;
+ }
+
+ ph_image_off2=PgCreateLayerSurface(1, 0, photon_format_idx,
width, height, Pg_OSC_MEM_PAGE_ALIGN);
+ if (ph_image_off!=NULL)
+ {
+ ph_surface_data2=PdGetOffscreenContextPtr(ph_image_off2);
+ }
+
+ /* Lock layer modifications by other applications */
+ PgLockLayer(1);
+ }
+
+ /* Try to use an offscreen renderer */
+ if (phrender_type==PHRENDER_USE_NONE)
+ {
+ ph_image_off=PdCreateOffscreenContext(photon_display_format,
width, height,
+ Pg_OSC_MEM_2D_WRITABLE | Pg_OSC_MEM_2D_READABLE |
Pg_OSC_MEM_PAGE_ALIGN);
+ if (ph_image_off!=NULL)
+ {
+ phrender_type=PHRENDER_USE_OFFSCREEN;
+ ph_surface_data=PdGetOffscreenContextPtr(ph_image_off);
+ ph_surface_width=ph_image_off->dim.w;
+ ph_surface_height=ph_image_off->dim.h;
+ ph_surface_pitch=ph_image_off->pitch;
+ }
+ }
+
+ /* Try to use an software offscren renderer */
+ if (phrender_type==PHRENDER_USE_NONE)
+ {
+ ph_image_off=PdCreateOffscreenContext(photon_display_format,
width, height,
+ Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_MEM_SYS_ONLY |
+ Pg_OSC_MEM_HINT_CPU_READ | Pg_OSC_MEM_HINT_CPU_WRITE);
+ if (ph_image_off!=NULL)
+ {
+ phrender_type=PHRENDER_USE_SWOFFSCREEN;
+ ph_surface_data=PdGetOffscreenContextPtr(ph_image_off);
+ ph_surface_width=ph_image_off->dim.w;
+ ph_surface_height=ph_image_off->dim.h;
+ ph_surface_pitch=ph_image_off->pitch;
+ }
+ }
+
+ /* Check if none of three renderers have been created */
+ if (phrender_type==PHRENDER_USE_NONE)
+ {
+ mp_msg(MSGT_VO, MSGL_ERR, "Can't create photon renderer!\n");
+ return -1;
+ }
+
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ photon_configure_layer();
+ }
+
+ switch (phrender_type)
+ {
+ case PHRENDER_USE_OFFSCREEN:
+ mp_msg(MSGT_VO, MSGL_INFO, "vo_photon: using hardware
offscreen (fast)\n");
+ break;
+ case PHRENDER_USE_SWOFFSCREEN:
+ mp_msg(MSGT_VO, MSGL_INFO, "vo_photon: using software
offscreen (slow)\n");
+ break;
+ case PHRENDER_USE_LAYER:
+ mp_msg(MSGT_VO, MSGL_INFO, "vo_photon: using direct
layer access (fastest)\n");
+ break;
+ }
+
+ return 0;
+}
+
+static void uninit(void)
+{
+ int active=0;
+
+ /* Unlock layer modifications */
+ PgUnlockLayer(1);
+
+ /* Disable layer on exit */
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ PgSetLayerArg(1, Pg_LAYER_ARG_LIST_BEGIN, 0, 0);
+ PgSetLayerArg(1, Pg_LAYER_ARG_ACTIVE, &active, sizeof(int));
+ PgSetLayerArg(1, Pg_LAYER_ARG_LIST_END, 0, 0);
+ }
+
+ if (ph_image_off2!=NULL)
+ {
+ PhDCRelease(ph_image_off2);
+ ph_image_off2=NULL;
+ }
+
+ if (ph_image_off!=NULL)
+ {
+ PhDCRelease(ph_image_off);
+ ph_image_off=NULL;
+ }
+
+ PtDestroyWidget(phwindow);
+}
+
+static void handle_phwindow_event(void)
+{
+ uint8_t eventbuffer[8192];
+ PhEvent_t* event=(PhEvent_t*)eventbuffer;
+ int32_t status;
+ uint32_t finish=0;
+
+ do {
+ status=PhEventPeek(event, 8192);
+ switch (status)
+ {
+ case Ph_RESIZE_MSG:
+ {
+ mp_msg(MSGT_VO, MSGL_ERR, "Can't get window event\n");
+ return;
+ }
+ break;
+ case Ph_EVENT_MSG:
+ {
+ /* Pass event to Widgets Toolkit */
+ PtEventHandler(event);
+
+ /* Event is ready */
+ switch (event->type)
+ {
+ case Ph_EV_WM:
+ {
+ PhWindowEvent_t* wmevent=NULL;
+
+ /* Get associated event data */
+ wmevent=PhGetData(event);
+ if (wmevent==NULL)
+ {
+ break;
+ }
+
+ switch (wmevent->event_f)
+ {
+ case Ph_WM_RESIZE:
+ {
+
phwindow_event_flags|=PHW_WINDOW_CHANGE_SIZE;
+
phwindow_event_flags|=PHW_WINDOW_CHANGE_POSITION;
+
phwindow_event_flags&=~(PHW_WINDOW_MAXIMIZE_EVENT);
+
phwindow_dimension=wmevent->size;
+ phwindow_position=wmevent->pos;
+ }
+ break;
+ case Ph_WM_MAX:
+ {
+ /* Avoid double
maximize events */
+ if
((phwindow_event_flags & PHW_WINDOW_MAXIMIZE_EVENT)==0)
+ {
+ PhDim_t* current_size;
+
+ PtFlush();
+
PtGetResource(phwindow, Pt_ARG_DIM, ¤t_size, 0);
+
+
phwindow_event_flags|=PHW_WINDOW_CHANGE_SIZE;
+
phwindow_event_flags|=PHW_WINDOW_CHANGE_POSITION;
+
phwindow_event_flags|=PHW_WINDOW_MAXIMIZE_EVENT;
+
phwindow_old_dimension=phwindow_dimension;
+
phwindow_old_position=phwindow_position;
+
phwindow_dimension=*current_size;
+ phwindow_position.x=0;
+ phwindow_position.y=0;
+
+
PtSetResource(phwindow, Pt_ARG_WINDOW_STATE, Pt_TRUE,
+ Ph_WM_STATE_ISMAX);
+ PtFlush();
+ }
+ }
+ break;
+ case Ph_WM_RESTORE:
+ {
+
phwindow_event_flags|=PHW_WINDOW_CHANGE_SIZE;
+
phwindow_event_flags|=PHW_WINDOW_CHANGE_POSITION;
+
phwindow_event_flags&=~(PHW_WINDOW_MAXIMIZE_EVENT);
+
+
phwindow_dimension=phwindow_old_dimension;
+
phwindow_position=phwindow_old_position;
+
+
PtSetResource(phwindow, Pt_ARG_WINDOW_STATE, Pt_FALSE,
+ Ph_WM_STATE_ISMAX);
+ PtFlush();
+ }
+ break;
+ case Ph_WM_MOVE:
+ {
+ PhPoint_t* current_position;
+
+ PtFlush();
+
PtGetResource(phwindow, Pt_ARG_POS, ¤t_position, 0);
+
phwindow_position=*current_position;
+
phwindow_event_flags|=PHW_WINDOW_CHANGE_POSITION;
+
phwindow_event_flags&=~(PHW_WINDOW_MAXIMIZE_EVENT);
+ }
+ break;
+ case Ph_WM_CLOSE:
+ {
+
phwindow_event_flags|=PHW_WINDOW_EXIT_REQUESTED;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ case 0:
+ {
+ /* All events are read */
+ finish=1;
+ }
+ break;
+ case -1:
+ {
+ /* Error occured in event reading */
+ mp_msg(MSGT_VO, MSGL_ERR, "Can't read window event\n");
+ return;
+ }
+ break;
+ }
+
+ if (finish!=0)
+ {
+ break;
+ }
+ } while (1);
+}
+
+static void check_events(void)
+{
+ if ((phwindow_fullscreen) && (!phwindow_fullscreen_set))
+ {
+ struct vo_rect src_rect;
+ struct vo_rect dst_rect;
+ struct vo_rect borders;
+ PhRect_t workspace_rect;
+
+ PhWindowQueryVisible(Ph_QUERY_WORKSPACE, 0,
PhInputGroup(NULL), &workspace_rect);
+ phwindow_fs_dimension.w=photon_screen_width;
+ phwindow_fs_dimension.h=photon_screen_height;
+ phwindow_fs_position.x=workspace_rect.ul.x-5;
+ phwindow_fs_position.y=workspace_rect.ul.y-23;
+ PtSetResource(phwindow, Pt_ARG_POS, &phwindow_fs_position, 0);
+ PtSetResource(phwindow, Pt_ARG_DIM, &phwindow_fs_dimension, 0);
+ PtSetResource(phoscontainer, Pt_ARG_DIM, &phwindow_fs_dimension, 0);
+ PtSetResource(phrawcontainer, Pt_ARG_DIM, &phwindow_fs_dimension, 0);
+ PtSetResource(phoscontainer, Pt_ARG_DIM, &phwindow_fs_dimension, 0);
+ PtSetResource(phwindow, Pt_ARG_DIM, &phwindow_fs_dimension, 0);
+ PtSetResource(phrawcontainer, Pt_ARG_CURSOR_TYPE, Ph_CURSOR_NONE, 0);
+ phwindow_fullscreen_set=VO_TRUE;
+ vo_dwidth=photon_screen_width;
+ vo_dheight=photon_screen_height;
+
+ calc_src_dst_rects(photon_video_width, photon_video_height,
&src_rect, &dst_rect, &borders, NULL);
+
+ photon_source_video_pos_x=src_rect.left;
+ photon_source_video_pos_y=src_rect.top;
+ photon_source_video_width=src_rect.width;
+ photon_source_video_height=src_rect.height;
+
+ photon_target_video_pos_x=dst_rect.left;
+ photon_target_video_pos_y=dst_rect.top;
+ photon_target_video_width=dst_rect.width;
+ photon_target_video_height=dst_rect.height;
+
+ PtDamageWidget(phrawcontainer);
+ PtFlush();
+
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ photon_configure_layer();
+ }
+ }
+
+ if ((!phwindow_fullscreen) && (!phwindow_fullscreen_set))
+ {
+ struct vo_rect src_rect;
+ struct vo_rect dst_rect;
+ struct vo_rect borders;
+
+ PtSetResource(phwindow, Pt_ARG_DIM, &phwindow_dimension, 0);
+ PtSetResource(phoscontainer, Pt_ARG_DIM, &phwindow_dimension, 0);
+ PtSetResource(phrawcontainer, Pt_ARG_DIM, &phwindow_dimension, 0);
+ PtSetResource(phoscontainer, Pt_ARG_DIM, &phwindow_dimension, 0);
+ PtSetResource(phwindow, Pt_ARG_DIM, &phwindow_dimension, 0);
+ PtSetResource(phwindow, Pt_ARG_POS, &phwindow_position, 0);
+ PtSetResource(phrawcontainer, Pt_ARG_CURSOR_TYPE,
Ph_CURSOR_POINTER, 0);
+ phwindow_fullscreen_set=VO_TRUE;
+ vo_dwidth=phwindow_dimension.w;
+ vo_dheight=phwindow_dimension.h;
+
+ calc_src_dst_rects(photon_video_width, photon_video_height,
&src_rect, &dst_rect, &borders, NULL);
+
+ photon_source_video_pos_x=src_rect.left;
+ photon_source_video_pos_y=src_rect.top;
+ photon_source_video_width=src_rect.width;
+ photon_source_video_height=src_rect.height;
+
+ photon_target_video_pos_x=dst_rect.left;
+ photon_target_video_pos_y=dst_rect.top;
+ photon_target_video_width=dst_rect.width;
+ photon_target_video_height=dst_rect.height;
+
+ PtDamageWidget(phrawcontainer);
+ PtFlush();
+
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ photon_configure_layer();
+ }
+ }
+
+ handle_phwindow_event();
+ if (phwindow_event_flags & PHW_WINDOW_EXIT_REQUESTED)
+ {
+ phwindow_event_flags&=~(PHW_WINDOW_EXIT_REQUESTED);
+ mplayer_put_key(KEY_ESC);
+ }
+ if (phwindow_event_flags & PHW_WINDOW_CHANGE_POSITION)
+ {
+ vo_dx=phwindow_position.x;
+ vo_dy=phwindow_position.y;
+ PtSetResource(phwindow, Pt_ARG_POS, &phwindow_position, 0);
+ PtFlush();
+
+ phwindow_event_flags&=~(PHW_WINDOW_CHANGE_POSITION);
+
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ photon_configure_layer();
+ }
+ }
+ if (phwindow_event_flags & PHW_WINDOW_CHANGE_SIZE)
+ {
+ struct vo_rect src_rect;
+ struct vo_rect dst_rect;
+ struct vo_rect borders;
+
+ vo_dwidth=phwindow_dimension.w;
+ vo_dheight=phwindow_dimension.h;
+
+ calc_src_dst_rects(photon_video_width, photon_video_height,
&src_rect, &dst_rect, &borders, NULL);
+
+ photon_source_video_pos_x=src_rect.left;
+ photon_source_video_pos_y=src_rect.top;
+ photon_source_video_width=src_rect.width;
+ photon_source_video_height=src_rect.height;
+
+ photon_target_video_pos_x=dst_rect.left;
+ photon_target_video_pos_y=dst_rect.top;
+ photon_target_video_width=dst_rect.width;
+ photon_target_video_height=dst_rect.height;
+
+ PtSetResource(phwindow, Pt_ARG_DIM, &phwindow_dimension, 0);
+ PtSetResource(phoscontainer, Pt_ARG_DIM, &phwindow_dimension, 0);
+ PtSetResource(phrawcontainer, Pt_ARG_DIM, &phwindow_dimension, 0);
+ PtSetResource(phoscontainer, Pt_ARG_DIM, &phwindow_dimension, 0);
+ PtSetResource(phwindow, Pt_ARG_DIM, &phwindow_dimension, 0);
+
+ phwindow_event_flags&=~(PHW_WINDOW_CHANGE_SIZE);
+
+ PtDamageWidget(phrawcontainer);
+ PtFlush();
+
+ if (phrender_type==PHRENDER_USE_LAYER)
+ {
+ photon_configure_layer();
+ }
+ }
+}
+
+static int preinit(const char *arg)
+{
+ PdOffscreenContext_t* main_display_ctx=NULL;
+ PhRect_t workspace_rect;
+ int jt;
+
+ /* Initialize Photon */
+ if (!phinited)
+ {
+ if (PtInit(NULL)==-1)
+ {
+ mp_msg(MSGT_VO, MSGL_ERR, "Can't connect to Photon\n");
+ return -1;
+ }
+ phinited=1;
+ }
+
+ /* Clear layer list */
+ jt=0;
+ do {
+ if ((photon_layer_map[jt].layer_id==0) &&
(photon_layer_map[jt].mp_id==0))
+ {
+ break;
+ }
+ photon_layer_map[jt].found=0;
+ photon_layer_map[jt].format_idx=0;
+ jt++;
+ } while(1);
+
+ phrender_type=PHRENDER_USE_NONE;
+
+ /* Get display pixel format for a conversion routines */
+ photon_display_format=Pg_IMAGE_DIRECT_565;
+
+ /* Try to make duplicate of display context */
+ main_display_ctx=PdCreateOffscreenContext(0, 0, 0, Pg_OSC_MAIN_DISPLAY);
+ /* Check if underlying driver has full support of layer */
+ if (main_display_ctx!=NULL)
+ {
+ photon_display_format=main_display_ctx->format;
+ photon_screen_width=main_display_ctx->dim.w;
+ photon_screen_height=main_display_ctx->dim.h;
+ PhDCRelease(main_display_ctx);
+ }
+ else
+ {
+ PgDisplaySettings_t mode_settings;
+ PgVideoModeInfo_t mode_info;
+
+ /* In very rare cases we have to check display format in the video */
+ /* mode settings. If video mode is not generic, this function fails */
+ if (PgGetVideoMode(&mode_settings)==0)
+ {
+ if (PgGetVideoModeInfo(mode_settings.mode, &mode_info)==0)
+ {
+ photon_display_format=mode_info.type;
+ photon_screen_width=mode_info.width;
+ photon_screen_height=mode_info.height;
+ }
+ else
+ {
+ mp_msg(MSGT_VO, MSGL_ERR, "Can't get display pixel format\n");
+ return -1;
+ }
+ }
+ else
+ {
+ mp_msg(MSGT_VO, MSGL_ERR, "Can't get display pixel format\n");
+ return -1;
+ }
+ }
+
+ /* Query virtual desktop settings */
+ PhWindowQueryVisible(Ph_QUERY_WORKSPACE, 0, PhInputGroup(NULL),
&workspace_rect);
+ xinerama_x=workspace_rect.ul.x;
+ xinerama_y=workspace_rect.ul.y;
+
+ /* Try to use a direct layer renderer */
+ if (phrender_type==PHRENDER_USE_NONE)
+ {
+ PgLayerCaps_t lcaps;
+ int layer_formats=0;
+ int status;
+ int it;
+
+ for (it=0; it<256; it++)
+ {
+ status=PgGetLayerCaps(1, it, &lcaps);
+ if (status==-1)
+ {
+ if (errno==EOPNOTSUPP)
+ {
+ layer_formats=0;
+ break;
+ }
+ if (errno==ENXIO)
+ {
+ layer_formats=0;
+ break;
+ }
+ if (errno==EINVAL)
+ {
+ break;
+ }
+ }
+
+ jt=0;
+ do {
+ if ((photon_layer_map[jt].layer_id==0) &&
(photon_layer_map[jt].mp_id==0))
+ {
+ break;
+ }
+ if (photon_layer_map[jt].layer_id==lcaps.format)
+ {
+ photon_layer_map[jt].found=1;
+ photon_layer_map[jt].format_idx=it;
+ layer_formats++;
+ }
+ jt++;
+ } while(1);
+ }
+
+ if (layer_formats!=0)
+ {
+ int layer_active=0;
+ int status;
+
+ status=PgSetLayerArg(1, Pg_LAYER_ARG_LIST_BEGIN, 0, 0);
+ if (status==0)
+ {
+ status=PgSetLayerArg(1, Pg_LAYER_ARG_ACTIVE,
&layer_active, sizeof(int));
+ if (status==0)
+ {
+ status=PgSetLayerArg(1, Pg_LAYER_ARG_LIST_END, 0, 0);
+ if (status==0)
+ {
+ phrender_type=PHRENDER_USE_LAYER;
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static uint32_t get_image(mp_image_t* mpi)
+{
+ /* Check if it is already has direct rendering flag */
+ if ((mpi->flags & MP_IMGFLAG_DIRECT)==MP_IMGFLAG_DIRECT)
+ {
+ return VO_TRUE;
+ }
+
+ /* video memory reading is very slow operation */
+ if ((mpi->flags & MP_IMGFLAG_READABLE)==MP_IMGFLAG_READABLE)
+ {
+ return VO_FALSE;
+ }
+
+ /* Codec must accept video driver's stride */
+ if ((mpi->flags & MP_IMGFLAG_ACCEPT_STRIDE)!=MP_IMGFLAG_ACCEPT_STRIDE)
+ {
+ return VO_FALSE;
+ }
+
+ if ((mpi->type!=MP_IMGTYPE_STATIC) && (mpi->type!=MP_IMGTYPE_TEMP))
+ {
+ return VO_FALSE;
+ }
+
+ /* Check image size and image pixel format */
+ if ((mpi->imgfmt!=photon_mplayer_format) ||
(photon_video_width!=mpi->width) ||
+ (photon_video_height!=mpi->height))
+ {
+ return VO_FALSE;
+ }
+
+ mpi->flags|=MP_IMGFLAG_DIRECT;
+ if (ph_image_current==0)
+ {
+ mpi->planes[0]=ph_surface_data;
+ mpi->stride[0]=ph_surface_pitch;
+ }
+ else
+ {
+ mpi->planes[0]=ph_surface_data2;
+ mpi->stride[0]=ph_surface_pitch;
+ }
+
+ return VO_TRUE;
+}
+
+static uint32_t put_image(mp_image_t* mpi)
+{
+ switch (phrender_type)
+ {
+ case PHRENDER_USE_LAYER:
+ case PHRENDER_USE_OFFSCREEN:
+ case PHRENDER_USE_SWOFFSCREEN:
+ {
+ ph_src_rect.ul.x=photon_source_video_pos_x;
+ ph_src_rect.ul.y=photon_source_video_pos_y;
+
ph_src_rect.lr.x=photon_source_video_pos_x+photon_source_video_width-1;
+
ph_src_rect.lr.y=photon_source_video_pos_y+photon_source_video_height-1;
+
+ ph_dst_rect.ul.x=photon_target_video_pos_x;
+ ph_dst_rect.ul.y=photon_target_video_pos_y;
+
ph_dst_rect.lr.x=photon_target_video_pos_x+photon_target_video_width-1;
+
ph_dst_rect.lr.y=photon_target_video_pos_y+photon_target_video_height-1;
+ }
+ break;
+ }
+
+ /* Check if it direct rendering flag, we have nothing todo then */
+ if ((mpi->flags & MP_IMGFLAG_DIRECT)==MP_IMGFLAG_DIRECT)
+ {
+ return VO_TRUE;
+ }
+
+ if (mpi->stride[0]==ph_surface_pitch)
+ {
+ if (ph_image_current==0)
+ {
+ fast_memcpy(ph_surface_data, mpi->planes[0],
+ ph_surface_pitch < mpi->stride[0] ? ph_surface_pitch
: mpi->stride[0]*mpi->height);
+ }
+ else
+ {
+ fast_memcpy(ph_surface_data2, mpi->planes[0],
+ ph_surface_pitch < mpi->stride[0] ? ph_surface_pitch
: mpi->stride[0]*mpi->height);
+ }
+ }
+ else
+ {
+ int it;
+ int pitch=ph_surface_pitch < mpi->stride[0] ?
ph_surface_pitch : mpi->stride[0];
+
+ for (it=0; it<mpi->height; it++)
+ {
+ if (ph_image_current==0)
+ {
+ fast_memcpy(ph_surface_data+it*ph_surface_pitch,
mpi->planes[0]+it*mpi->stride[0], pitch);
+ }
+ else
+ {
+ fast_memcpy(ph_surface_data2+it*ph_surface_pitch,
mpi->planes[0]+it*mpi->stride[0], pitch);
+ }
+ }
+ }
+
+ return VO_TRUE;
+}
+
+static int control(uint32_t request, void* data)
+{
+ switch (request)
+ {
+ case VOCTRL_QUERY_FORMAT:
+ return query_format(*((uint32_t*)data));
+ case VOCTRL_GUI_NOWINDOW:
+ return VO_FALSE;
+ case VOCTRL_GUISUPPORT:
+ return VO_TRUE;
+ case VOCTRL_GET_PANSCAN:
+ return VO_TRUE;
+ case VOCTRL_SET_PANSCAN:
+ phwindow_event_flags|=PHW_WINDOW_CHANGE_SIZE;
+ return VO_TRUE;
+ case VOCTRL_FULLSCREEN:
+ if (phwindow_fullscreen==VO_TRUE)
+ {
+ phwindow_fullscreen=VO_FALSE;
+ }
+ else
+ {
+ phwindow_fullscreen=VO_TRUE;
+ }
+ phwindow_fullscreen_set=VO_FALSE;
+ return VO_TRUE;
+ case VOCTRL_GET_IMAGE:
+ return get_image(data);
+ case VOCTRL_DRAW_IMAGE:
+ return put_image(data);
+ case VOCTRL_ONTOP:
+ if (phwindow_ontop==VO_TRUE)
+ {
+ phwindow_ontop=VO_FALSE;
+ }
+ else
+ {
+ phwindow_ontop=VO_TRUE;
+ }
+ return VO_TRUE;
+ case VOCTRL_UPDATE_SCREENINFO:
+ vo_screenwidth=photon_screen_width;
+ vo_screenheight=photon_screen_height;
+ switch (photon_display_format)
+ {
+ case Pg_IMAGE_DIRECT_1555:
+ vo_depthonscreen=15;
+ ph_chroma_color=PgRGBA(0x0F, 0x1F, 0x0F, 0x80);
+ break;
+ case Pg_IMAGE_DIRECT_565:
+ vo_depthonscreen=16;
+ ph_chroma_color=PgRGBA(0x0F, 0x0F, 0x0F, 0x80);
+ break;
+ case Pg_IMAGE_DIRECT_888:
+ vo_depthonscreen=24;
+ ph_chroma_color=PgRGBA(0x01, 0x02, 0x03, 0x00);
+ break;
+ case Pg_IMAGE_DIRECT_8888:
+ vo_depthonscreen=32;
+ ph_chroma_color=PgRGBA(0x01, 0x02, 0x03, 0x80);
+ break;
+ }
+ aspect_save_screenres(vo_screenwidth, vo_screenheight);
+ return VO_TRUE;
+ }
+
+ return VO_NOTIMPL;
+}
More information about the MPlayer-dev-eng
mailing list