aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Uoti Urpala <uau@glyph.nonexistent.invalid>2010-01-08 01:05:30 +0200
committerGravatar Uoti Urpala <uau@glyph.nonexistent.invalid>2010-01-08 01:05:30 +0200
commit231b33a02fae95b260120349040106bfa34a3750 (patch)
tree23c4de0e6263b2d99966348d7003177b3b3e3740
parent52126e574c7872ca95e7974cfe5445421b74f24c (diff)
parent92cd6dc3e916ae4275ff05d2b238fc778cfbfc6b (diff)
Merge svn changes up to r30165
-rw-r--r--DOCS/man/fr/mplayer.1133
-rw-r--r--DOCS/man/zh_CN/mplayer.14
-rw-r--r--Makefile2
-rw-r--r--codec-cfg.c11
-rw-r--r--etc/codecs.conf51
-rw-r--r--fmt-conversion.c11
-rw-r--r--libao2/ao_alsa.c9
-rw-r--r--libao2/ao_dart.c2
-rw-r--r--libmpcodecs/img_format.c64
-rw-r--r--libmpcodecs/img_format.h32
-rw-r--r--libmpcodecs/mp_image.c59
-rw-r--r--libmpcodecs/mp_image.h48
-rw-r--r--libmpcodecs/vd_ffmpeg.c4
-rw-r--r--libmpcodecs/vf.c39
-rw-r--r--libmpcodecs/vf_scale.c26
-rw-r--r--libvo/csputils.c160
-rw-r--r--libvo/csputils.h56
-rw-r--r--libvo/gl_common.c143
-rw-r--r--libvo/gl_common.h12
-rw-r--r--libvo/vo_gl.c105
-rw-r--r--libvo/vo_gl2.c65
-rw-r--r--libvo/vo_ivtv.c2
-rw-r--r--libvo/vo_jpeg.c15
-rw-r--r--libvo/vo_png.c9
-rw-r--r--libvo/vo_pnm.c2
-rw-r--r--libvo/vo_v4l2.c2
-rw-r--r--libvo/vo_xv.c15
-rw-r--r--libvo/vo_xvmc.c4
-rw-r--r--libvo/vo_zr2.c10
-rw-r--r--m_option.c11
-rw-r--r--stream/http.c7
-rw-r--r--subopt-helper.c14
-rw-r--r--subopt-helper.h4
33 files changed, 753 insertions, 378 deletions
diff --git a/DOCS/man/fr/mplayer.1 b/DOCS/man/fr/mplayer.1
index 61ae44e954..f1de6a4065 100644
--- a/DOCS/man/fr/mplayer.1
+++ b/DOCS/man/fr/mplayer.1
@@ -1,4 +1,4 @@
-.\" synced with r29731
+.\" synced with r30135
.\" Encoding: iso-8859-1
.\" MPlayer (C) 2000-2009 MPlayer Team
.\" The English man page was/is done by Gabucino, Diego Biurrun, Jonas Jermann
@@ -188,7 +188,12 @@ rotation, redimensionnement, bruit, conversion RGB/\:YUV) et bien plus.
.PP
.B gmplayer
est l'interface graphique de MPlayer.
-Il possède les mêmes options que MPlayer.
+Elle possède les mêmes options que MPlayer, cela dit toutes peuvent ne
+pas fonctionner correctement à cause des des conflits avec la
+configuration de l'IHM graphique (stocké dans gui.conf).
+Certaines options peuvent êtres redéfinies par la configuration de
+gui.conf, et certaines autres peuvent être définies de façon
+permanente par gui.conf
.PP
Des exemples d'usage pour vous familiariser rapidement sont disponibles
à la fin de cette page de manuel.
@@ -447,9 +452,10 @@ Confirme le choix.
.RS
.
.
-(Les touches suivantes ne sont valides que si MPlayer a été
-compilé avec le support télétexte\ : elles peuvent être utilisées pour contrôler
-le télétexte de la TV.)
+(Les touches suivantes ne sont valides que si MPlayer a été compilé
+avec le support télétexte\ : elles servent à contrôler le télétexte de
+la TV, dont les données peuvent provenir d'une source TV analogique ou
+par MPEG Transport Stream.)
.RE
.PP
.PD 0
@@ -551,18 +557,14 @@ Vous pouvez également écrire des fichiers de config spécifiques à un fichier.
Si vous souhaitez avoir un fichier de config pour un fichier nommé 'film.avi',
créez un fichier nommé 'film.avi.conf' contenant les options spécifiques à ce
fichier et placez-le dans ~/.mplayer/.
-
Si un tel fichier de configuration se trouve dans le même répertoire,
aucun fichier de configuration spécifique ne sera lu depuis
~/.mplayer/.
-
De plus, l'option \-use\-filedir\-conf permet de définir des fichiers
de configuration spécifiques à un répertoire.
-
Pour ce faire, MPlayer essaye de charger un fichier mplayer.conf
depuis le même répertoire que celui du fichier joué, et essaye ensuite
de charger un fichier de configuration spécifique.
-
.PP
.I EXEMPLE DE FICHIER DE CONFIGURATION MPLAYER\ :
.sp 1
@@ -1299,7 +1301,7 @@ Permet au socket d'être ré-utilisé par un autre processus aussitôt qu'il
est fermé.
.
.TP
-.B \-bandwidth <valeur> (réseau uniquement)
+.B \-bandwidth <octets> (réseau uniquement)
Spécifie la bande passante maximum pour le streaming par le réseau (pour les
serveurs capables d'envoyer du contenu à différents débits).
Utile si vous voulez voir en direct avec une connexion lente des médias
@@ -1400,6 +1402,8 @@ Stereo
Surround
.IPs 6
5.1 complet
+.IPs 8
+7.1 complet
.RE
.PD 1
.
@@ -3266,8 +3270,9 @@ Utilise l'astuce _WIN_LAYER avec la couche par défaut.
Utilise l'astuce _WIN_LAYER avec le numéro de couche.
.IPs netwm
Force le style NETWM.
-.IPs none
-N'initialise pas la couche plein-écran de la fenêtre.
+.IPs "none\ "
+Efface la liste des modes\ ; vous pouvez ajouter des modes à activer
+plus tard.
.IPs stays_on_top
Utilise l'astuce _NETWM_STATE_STAYS_ON_TOP si disponible.
.REss
@@ -3298,11 +3303,11 @@ alors les coordonnées x et y sont relatives aux coin supérieur gauche de la
fenêtre au lieu celui de l'écran.
Les coordonnées sont relatives à l'écran donné par l'option \-xineramascreen
pour les pilotes de sortie vidéo gérant complètement l'option \-xineramascreen
-(direct3d, gl, gl2, vdpau, x11, xv, xvmc).
+(direct3d, gl, gl2, vdpau, x11, xv, xvmc, corevideo).
.br
.I NOTE:
Cette option n'est permise que par les pilotes de sortie vidéo x11, xmga, xv,
-xvmc, xvidix, gl, gl2, directx, fbdev et tdfxfb.
+xvmc, xvidix, gl, gl2, directx, fbdev, tdfxfb et corevideo.
.sp 1
.I EXEMPLE:
.PD 0
@@ -3371,6 +3376,10 @@ La valeur 1 signifie des pixels carrés (correct
pour presque tous les écrans LCD).
.
.TP
+.B \-name (X11 uniquement)
+Défini le nom de la classe de fenêtre.
+.
+.TP
.B \-nodouble
Désactive le double tamponnage (buffering), surtout à des fins de débogage.
Le double tamponnage évite les phénomènes de scintillement en plaçant
@@ -3461,6 +3470,17 @@ Si votre reposeur d'écran ne supporte ni l'API XSS, ni XResetScreenSaver,
alors veuillez utiliser \-heartbeat\-cmd à la place.
.
.TP
+.B \-title (voir aussi \-use\-filename\-title)
+Défini le titre de la fenêtre.
+Géré par tous les pilotes de sortie vidéos basés sur X11.
+.
+.TP
+.B \-use\-filename\-title (voir aussi \-title)
+Défini la barre de titre en fonction du nom de fichier du média, quand
+celui-ci n'est pas défini par \-title.
+Géré par tous les pilotes de sortie vidéos basés sur X11.
+.
+.TP
.B "\-vm \ \ \ "
Essaie de changer vers un autre mode vidéo.
Les pilotes de sortie vidéo dga, x11, xv, sdl et directx le permettent.
@@ -3496,7 +3516,8 @@ Fontionnera généralement uniquement avec "\-fstype \-fullscreen" ou
Cette option ne convient pas pour définir l'écran de démarrage (car l'affichage
se fera toujours en plein écran sur le moniteur donné), \-geometry est plus
approprié.
-Géré au moins par les pilotes de sortie vidéo direct3d, gl, gl2, x11, et xv.
+Géré au moins par les pilotes de sortie vidéo direct3d, gl, gl2, x11, xv et
+corevideo.
.
.TP
.B \-zrbw (\-vo zr uniquement)
@@ -3651,7 +3672,8 @@ Sélectionnne le pilote à utiliser comme source pour l'incrustation dans X11.
.PD 1
.
.TP
-.B vdpau (avec \-vc ffmpeg12vdpau, ffwmv3vdpau, ffvc1vdpau ou ffh264vdpau)
+.B vdpau (avec \-vc ffmpeg12vdpau, ffwmv3vdpau, ffvc1vdpau, ffh264vdpau,
+ou ffodivxvdpau)
Sortie vidéo utilisant VDPAU pour décoder les vidéos matériellement.
Gère aussi l'affichage de vidéos décodées en logiciel.
.PD 0
@@ -3693,6 +3715,37 @@ Utile quand la mémoire vidéo est lente.
.IPs pullup
Essaye d'appliquer un filtre téléciné inverse.
Nécessite un filtre de désentrelacement à adaptation de mouvement temporel.
+.IPs colorspace
+Sélectionne l'espace de couleur pour la conversion YUV vers RVB.
+En général, BT.601 est recommandé pour les contenus à définition standard
+(SD), et BT.709 pour la haute définition (HD)
+L'utilisation d'un espace de couleur inapproprié peut donner des
+couleurs trop ou pas assez saturées.
+.RSss
+.IPs 0
+Déduit l'espace de couleur en fonction de la résolution vidéo.
+Une vidéo dont la largeur est >= 1280 ou on la hauteur est > 576 est
+détectée comme HD et donc l'espace de couleur BT.709 sera utilisé.
+.IPs 1
+Utilise l'espace de couleur ITU-R BT.601 (par défaut).
+.IPs 2
+Utilise l'espace de couleur ITU-R BT.709.
+.IPs 3
+Utilise l'espace de couleur SMPTE-240M.
+.RE
+.IPs hqscaling
+.RSss
+.IPs 0
+Utilise la mise à l'échelle VDPAU (par défaut).
+.IPs 1\-9
+Utilise une mise à l'échelle de haute qualité (nécessite un matériel
+compatible).
+.RE
+.IPs force\-mixer
+Force l'utilisation du mixeur VDPAU, qui implémente toutes les options
+ci-dessus (par défaut).
+Utilisez noforce\-mixer pour permettre l'affichage de vidéos utilisant
+l'espace de couleur BGRA.
.RE
.PD 1
.
@@ -3985,6 +4038,9 @@ horizontal / n).
Requiert le support de GLX_SGI_swap_control pour fonctionner.
Avec certaines implémentation (la plupart/toutes?) ceci ne fonctionne
qu'en mode plein écran
+.IPs ycbcr
+Utilise l'extension GL_MESA_ycbcr_texture pour la conversion YUV vers RVB.
+Généralement plus lent que de réaliser cette conversion par logiciel.
.IPs yuv=<n>
Choisit le type de conversion YUV vers RGB.
.RSss
@@ -4038,10 +4094,6 @@ Le gamma du rouge, vert et bleu peut aussi être ajusté indépendement.
La vitesse de ce type de conversion dépend plus de la bande passante
de la carte vidéo que les autres méthodes.
.RE
-.IPs ycbcr
-Utilise l'extension GL_MESA_ycbcr_texture pour la conversion YUV vers RGB.
-Dans la plupart des cas, cela est probablement plus lent que de réaliser
-la conversion RGB par logiciel.
.IPs lscale=<n>
Sélection de la fonction de mise à l'échelle à utiliser pour la luminance.
Valide uniquement pour les modes yuv 2, 3, 4 et 6.
@@ -4083,6 +4135,12 @@ Utilise l'interpolation GL_LINEAR (par défaut), sinon utilise
GL_NEAREST comme texture customtex.
.IPs (no)customtrect
Utilise texture_rectangle comme texture customtex.
+.IPs (no)mipmapgen
+Permet la génération automatique de mipmaps pour la vidéo.
+Peut être utile combiné avec les instruction customprog et TXB
+pour implémenter des filtre de floutage à large diamètre.
+Très lent avec la plupart des implémentation OpenGL pour les formats
+non-RVB.
.RE
.sp 1
.RS
@@ -5372,14 +5430,15 @@ Défini la fréquence de coupure (en Hz).
Défini le niveau d'entrée des basses fréquences (en dixième de dB).
.IPs profile=<valeur>
Plusieurs profils sont disponibles\ :
+.PD 0
.RSs
-default\ : réglage par défaut (fcut=700, feed=45);
-.br
-cmoy: implémentation du circuit Chu Moy (fcut=700, feed=60);
-.br
-jmeier: implémentation du circuit Jan Meier (fcut=650, feed=95).
-.REss
-.PD 1
+.IPs default
+réglage par défaut (fcut=700, feed=45);
+.IPs "cmoy\ "
+implémentation du circuit Chu Moy (fcut=700, feed=60);
+.IPs jmeier
+implémentation du circuit Jan Meier (fcut=650, feed=95).
+.RE
.RE
.sp 1
.RS
@@ -5464,11 +5523,11 @@ d'entrée les canaux en trop seront tronqués.
.PD 0
.RSs
.IPs <nch>
-nombre de canaux de sortie (1\-6)
+nombre de canaux de sortie (1\-8)
.IPs "<nr>\ "
-nombre de routes (1\-6)
+nombre de routes (1\-8)
.IPs <from1:to1:from2:to2:from3:to3:...>
-Paires de nombres entre 0 and 5 définissant où router chaque canal.
+Paires de nombres entre 0 and 7 définissant où router chaque canal.
.RE
.sp 1
.RS
@@ -5575,7 +5634,7 @@ Un exemple de mixage de six canaux vers deux à l'aide de ce filtre peut
.PD 0
.RSs
.IPs "<n>\ \ "
-nombre de canaux de sortie (1\-6)
+nombre de canaux de sortie (1\-8)
.IPs <Lij>
Combien du canal i est mixé dans le canal de sortie j (0\-1).
En principe, vous avez un nombre spécifiant ce que faire avec le premier
@@ -5621,8 +5680,8 @@ aussi bas que possible.
Cela améliorera l'effet surround ou stéréo.
.IPs "<ca>\ "
Définit le numéro de canal vers lequel router le flux du caisson de basse.
-Le numéro de canal doit être compris entre 0 et 5 (par défaut\ : 5).
-Notez que le nombre de canaux sera automatiquement incrémenté jusqu'à <ch>
+Le numéro de canal doit être compris entre 0 et 7 (par défaut\ : 5).
+Notez que le nombre de canaux sera automatiquement incrémenté jusqu'à <ca>
si nécessaire.
.RE
.sp 1
@@ -5646,7 +5705,7 @@ fait une moyenne des canaux et l'atténue de moitié à la place.
.RSs
.IPs <ca>
Détermine le canal dans lequel insérer le canal central.
-Le numéro de canal peut être un nombre compris entre 0 et 5
+Le numéro de canal peut être un nombre compris entre 0 et 7
(par défaut\ : 5).
Notez que le nombre de canaux sera automatiquement augmenté à <ca>
si nécessaire.
@@ -5723,8 +5782,8 @@ Les aires de mémoire mappées contiennent une entête:
int nch /*nombre de canaux*/
int size /*taille du tampon*/
unsigned long long counter /*Utilisé pour garder la synchro, mis à jour
- chaque fois que de nouvelles données son
- exportées.*/
+ chaque fois que de nouvelles données son
+ exportées.*/
.fi
.sp 1
Le reste est charge utile, constitué de données 16bit (non-entrelacées).
@@ -7704,6 +7763,8 @@ disponible \- aucun fichier ne sera écrasé.
Ce filtre ne provoque pas de surcoût lorsqu'il n'est pas utilisé, et accepte
tous les espaces de couleur, donc ça ne pose pas de problème de l'ajouter par
défaut dans votre fichier de configuration.
+Assurez-vous que ce filtre est appliqué après tous les autres filtres vidéos,
+sinon l'image capturée ne correspondra pas à ce que vous voyez à l'écran.
.RE
.
.TP
diff --git a/DOCS/man/zh_CN/mplayer.1 b/DOCS/man/zh_CN/mplayer.1
index c2bf86f4f3..274ef7c2b8 100644
--- a/DOCS/man/zh_CN/mplayer.1
+++ b/DOCS/man/zh_CN/mplayer.1
@@ -1,4 +1,4 @@
-.\" sync with en/mplayer.1 r30053
+.\" sync with en/mplayer.1 r30135
.\" Encoding: UTF-8
.\" Reminder of hard terms which need better/final solution later:
.\" /capture; playtree in parent list; colorkey; retrace; desync; downmix;
@@ -1167,7 +1167,7 @@ MPlayer 在 verbose (\-v) 模å¼ä¸‹ä¼šæ‰“å°å¯ç”¨çš„语言。
å…许SOCKET在关闭åŽç«‹å³è¢«å…¶å®ƒè¿›ç¨‹é‡æ–°åˆ©ç”¨ã€‚
.
.TP
-.B \-bandwidth <å‚数值> (仅适用于网络)
+.B \-bandwidth <字节值> (仅适用于网络)
指定网络æµçš„最大带宽(用于æœåŠ¡å™¨å¯ä»¥ä»¥ä¸åŒå¸¦å®½ä¼ é€å†…容的情况)。
当你以慢速连接观看现场æµåª’体时有用。
对于 Real RTSP æµ, 也用æ¥è®¾ç½®æœ€å¤§çš„ä¼ é€å¸¦å®½
diff --git a/Makefile b/Makefile
index be0530ba86..67c2411599 100644
--- a/Makefile
+++ b/Makefile
@@ -538,7 +538,7 @@ SRCS_MPLAYER-$(ESD) += libao2/ao_esd.c
SRCS_MPLAYER-$(FBDEV) += libvo/vo_fbdev.c libvo/vo_fbdev2.c
SRCS_MPLAYER-$(GGI) += libvo/vo_ggi.c
SRCS_MPLAYER-$(GIF) += libvo/vo_gif89a.c
-SRCS_MPLAYER-$(GL) += libvo/gl_common.c libvo/vo_gl.c libvo/vo_gl2.c
+SRCS_MPLAYER-$(GL) += libvo/gl_common.c libvo/vo_gl.c libvo/vo_gl2.c libvo/csputils.c
SRCS_MPLAYER-$(GL_WIN32) += libvo/w32_common.c
SRCS_MPLAYER-$(GL_X11) += libvo/x11_common.c
diff --git a/codec-cfg.c b/codec-cfg.c
index 27e07c92ac..5a7b7c9d9b 100644
--- a/codec-cfg.c
+++ b/codec-cfg.c
@@ -155,9 +155,20 @@ static int add_to_format(char *s, char *alias,unsigned int *fourcc, unsigned int
{"NV21", IMGFMT_NV21},
{"YVU9", IMGFMT_YVU9},
{"IF09", IMGFMT_IF09},
+ {"444P16LE", IMGFMT_444P16_LE},
+ {"444P16BE", IMGFMT_444P16_BE},
+ {"422P16LE", IMGFMT_422P16_LE},
+ {"422P16BE", IMGFMT_422P16_BE},
+ {"420P16LE", IMGFMT_420P16_LE},
+ {"420P16BE", IMGFMT_420P16_BE},
+ {"444P16", IMGFMT_444P16},
+ {"422P16", IMGFMT_422P16},
+ {"420P16", IMGFMT_420P16},
+ {"420A", IMGFMT_420A},
{"444P", IMGFMT_444P},
{"422P", IMGFMT_422P},
{"411P", IMGFMT_411P},
+ {"440P", IMGFMT_440P},
{"Y800", IMGFMT_Y800},
{"Y8", IMGFMT_Y8},
diff --git a/etc/codecs.conf b/etc/codecs.conf
index 5f22c31a2d..be548cac61 100644
--- a/etc/codecs.conf
+++ b/etc/codecs.conf
@@ -1305,6 +1305,7 @@ videocodec ffmjpeg
dll mjpeg
out 444P
out 422P
+ out 440P
out YUY2 ; queried (conversion from yuv422p)
out YV12,I420,IYUV
out BGR32 ; lossless JPEG
@@ -1319,6 +1320,7 @@ videocodec ffmjpegb
dll mjpegb
out 444P
out 422P
+ out 440P
out YUY2 ; queryed (conversion from yuv422p)
out YV12,I420,IYUV
@@ -2058,7 +2060,7 @@ videocodec ffvp6a
fourcc VP6A
driver ffmpeg
dll "vp6a"
- out I420,YUY2,YV12
+ out 420A
videocodec ffvp6f
info "FFmpeg VP6 Flash"
@@ -2237,6 +2239,15 @@ videocodec tm20
guid 0x4cb63e61, 0xc611, 0x11D0, 0x83, 0xaa, 0x00, 0x00, 0x92, 0x90, 0x01, 0x84
out BGR32,BGR24,BGR16 flip
+videocodec tm2xvfw
+ info "TrueMotion 2.0"
+ status working
+ fourcc TM2X
+ fourcc TM2A TM2X
+ driver vfw
+ dll "tm2X.dll"
+ out BGR32,BGR24,BGR16 flip
+
videocodec tr20
info "TrueMotion RT"
status working
@@ -2627,6 +2638,14 @@ videocodec qtsvq1
dll "QuickTime.qts"
out YVU9
+videocodec ffv210
+ info "FFmpeg V210 - 10-bit"
+ status untested
+ fourcc v210
+ driver ffmpeg
+ dll v210
+ out 422P16
+
videocodec qtcine
info "cinewave uncompressed 10-bit codec"
status working
@@ -3769,7 +3788,7 @@ audiocodec ffaac
audiocodec ffflac
info "FFmpeg FLAC audio"
status working
- format 0x43614C66
+ fourcc "fLaC"
format 0xF1AC
driver ffmpeg
dll "flac"
@@ -4063,15 +4082,6 @@ audiocodec lpcm
driver ffmpeg
dll pcm_bluray
-audiocodec a52
- info "AC3-liba52"
- status working
- format 0x2000
- ; format 0x332D6361 ; ac-3 in mp4 -- not working
- fourcc dnet
- driver liba52
- dll "liba52"
-
audiocodec ffac3
info "FFmpeg AC-3"
status working
@@ -4091,12 +4101,14 @@ audiocodec ffeac3
driver ffmpeg
dll eac3
-audiocodec dts
- info "DTS-libdca"
+audiocodec a52
+ info "AC3-liba52"
status working
- format 0x2001
- format 0x86
- driver libdca
+ format 0x2000
+ ; format 0x332D6361 ; ac-3 in mp4 -- not working
+ fourcc dnet
+ driver liba52
+ dll "liba52"
audiocodec ffdca
info "FFmpeg DTS"
@@ -4106,6 +4118,13 @@ audiocodec ffdca
driver ffmpeg
dll "dca"
+audiocodec dts
+ info "DTS-libdca"
+ status working
+ format 0x2001
+ format 0x86
+ driver libdca
+
audiocodec ffmusepack7
info "Musepack sv7 audio codec"
comment "only works with libavformat demuxer"
diff --git a/fmt-conversion.c b/fmt-conversion.c
index 06699c6ee5..9371ab1a11 100644
--- a/fmt-conversion.c
+++ b/fmt-conversion.c
@@ -58,6 +58,16 @@ static const struct {
{IMGFMT_411P, PIX_FMT_YUV411P},
{IMGFMT_422P, PIX_FMT_YUV422P},
{IMGFMT_444P, PIX_FMT_YUV444P},
+ {IMGFMT_440P, PIX_FMT_YUV440P},
+
+ {IMGFMT_420A, PIX_FMT_YUVA420P},
+
+ {IMGFMT_420P16_LE, PIX_FMT_YUV420P16LE},
+ {IMGFMT_420P16_BE, PIX_FMT_YUV420P16BE},
+ {IMGFMT_422P16_LE, PIX_FMT_YUV422P16LE},
+ {IMGFMT_422P16_BE, PIX_FMT_YUV422P16BE},
+ {IMGFMT_444P16_LE, PIX_FMT_YUV444P16LE},
+ {IMGFMT_444P16_BE, PIX_FMT_YUV444P16BE},
// YUVJ are YUV formats that use the full Y range and not just
// 16 - 235 (see colorspaces.txt).
@@ -65,6 +75,7 @@ static const struct {
{IMGFMT_YV12, PIX_FMT_YUVJ420P},
{IMGFMT_422P, PIX_FMT_YUVJ422P},
{IMGFMT_444P, PIX_FMT_YUVJ444P},
+ {IMGFMT_440P, PIX_FMT_YUVJ440P},
{IMGFMT_XVMC_MOCO_MPEG2, PIX_FMT_XVMC_MPEG2_MC},
{IMGFMT_XVMC_IDCT_MPEG2, PIX_FMT_XVMC_MPEG2_IDCT},
diff --git a/libao2/ao_alsa.c b/libao2/ao_alsa.c
index 4c92597765..140b13a62a 100644
--- a/libao2/ao_alsa.c
+++ b/libao2/ao_alsa.c
@@ -271,10 +271,9 @@ static void print_help (void)
"[AO_ALSA] Sets device (change , to . and : to =)\n");
}
-static int str_maxlen(strarg_t *str) {
- if (str->len > ALSA_DEVICE_SIZE)
- return 0;
- return 1;
+static int str_maxlen(void *strp) {
+ strarg_t *str = strp;
+ return str->len <= ALSA_DEVICE_SIZE;
}
static int try_open_device(const char *device, int open_mode, int try_ac3)
@@ -336,7 +335,7 @@ static int init(int rate_hz, int channels, int format, int flags)
snd_pcm_uframes_t boundary;
const opt_t subopts[] = {
{"block", OPT_ARG_BOOL, &block, NULL},
- {"device", OPT_ARG_STR, &device, (opt_test_f)str_maxlen},
+ {"device", OPT_ARG_STR, &device, str_maxlen},
{NULL}
};
diff --git a/libao2/ao_dart.c b/libao2/ao_dart.c
index 58ee4d1886..e1df7d32f7 100644
--- a/libao2/ao_dart.c
+++ b/libao2/ao_dart.c
@@ -148,7 +148,7 @@ static int init(int rate, int channels, int format, int flags)
const opt_t subopts[] = {
{"share", OPT_ARG_BOOL, &fShare, NULL},
- {"bufsize", OPT_ARG_INT, &nDartSamples, (opt_test_f)int_non_neg},
+ {"bufsize", OPT_ARG_INT, &nDartSamples, int_non_neg},
{NULL}
};
diff --git a/libmpcodecs/img_format.c b/libmpcodecs/img_format.c
index 7d20a77cc7..31cb3591bb 100644
--- a/libmpcodecs/img_format.c
+++ b/libmpcodecs/img_format.c
@@ -37,6 +37,13 @@ const char *vo_format_name(int format)
case IMGFMT_CLPL: return "Planar CLPL";
case IMGFMT_Y800: return "Planar Y800";
case IMGFMT_Y8: return "Planar Y8";
+ case IMGFMT_420P16_LE: return "Planar 420P 16-bit little-endian";
+ case IMGFMT_420P16_BE: return "Planar 420P 16-bit big-endian";
+ case IMGFMT_422P16_LE: return "Planar 422P 16-bit little-endian";
+ case IMGFMT_422P16_BE: return "Planar 422P 16-bit big-endian";
+ case IMGFMT_444P16_LE: return "Planar 444P 16-bit little-endian";
+ case IMGFMT_444P16_BE: return "Planar 444P 16-bit big-endian";
+ case IMGFMT_420A: return "Planar 420P with alpha";
case IMGFMT_444P: return "Planar 444P";
case IMGFMT_422P: return "Planar 422P";
case IMGFMT_411P: return "Planar 411P";
@@ -79,3 +86,60 @@ const char *vo_format_name(int format)
snprintf(unknown_format,20,"Unknown 0x%04x",format);
return unknown_format;
}
+
+int mp_get_chroma_shift(int format, int *x_shift, int *y_shift)
+{
+ int xs = 0, ys = 0;
+ int bpp;
+ int bpp_factor = 1;
+ int err = 0;
+ switch (format) {
+ case IMGFMT_420P16_LE:
+ case IMGFMT_420P16_BE:
+ bpp_factor = 2;
+ case IMGFMT_420A:
+ case IMGFMT_I420:
+ case IMGFMT_IYUV:
+ case IMGFMT_YV12:
+ xs = 1;
+ ys = 1;
+ break;
+ case IMGFMT_IF09:
+ case IMGFMT_YVU9:
+ xs = 2;
+ ys = 2;
+ break;
+ case IMGFMT_444P16_LE:
+ case IMGFMT_444P16_BE:
+ bpp_factor = 2;
+ case IMGFMT_444P:
+ xs = 0;
+ ys = 0;
+ break;
+ case IMGFMT_422P16_LE:
+ case IMGFMT_422P16_BE:
+ bpp_factor = 2;
+ case IMGFMT_422P:
+ xs = 1;
+ ys = 0;
+ break;
+ case IMGFMT_411P:
+ xs = 2;
+ ys = 0;
+ break;
+ case IMGFMT_440P:
+ xs = 0;
+ ys = 1;
+ break;
+ default:
+ err = 1;
+ break;
+ }
+ if (x_shift) *x_shift = xs;
+ if (y_shift) *y_shift = ys;
+ bpp = 8 + (16 >> (xs + ys));
+ if (format == IMGFMT_420A)
+ bpp += 8;
+ bpp *= bpp_factor;
+ return err ? 0 : bpp;
+}
diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h
index 4c917b01e4..6bab56632d 100644
--- a/libmpcodecs/img_format.h
+++ b/libmpcodecs/img_format.h
@@ -71,8 +71,33 @@
#define IMGFMT_444P 0x50343434
#define IMGFMT_422P 0x50323234
#define IMGFMT_411P 0x50313134
+#define IMGFMT_440P 0x50303434
#define IMGFMT_HM12 0x32314D48
+// 4:2:0 planar with alpha
+#define IMGFMT_420A 0x41303234
+
+#define IMGFMT_444P16_LE 0x51343434
+#define IMGFMT_444P16_BE 0x34343451
+#define IMGFMT_422P16_LE 0x51323234
+#define IMGFMT_422P16_BE 0x34323251
+#define IMGFMT_420P16_LE 0x51303234
+#define IMGFMT_420P16_BE 0x34323051
+#if HAVE_BIGENDIAN
+#define IMGFMT_444P16 IMGFMT_444P16_BE
+#define IMGFMT_422P16 IMGFMT_422P16_BE
+#define IMGFMT_420P16 IMGFMT_420P16_BE
+#else
+#define IMGFMT_444P16 IMGFMT_444P16_LE
+#define IMGFMT_422P16 IMGFMT_422P16_LE
+#define IMGFMT_420P16 IMGFMT_420P16_LE
+#endif
+
+#define IMGFMT_IS_YUVP16_LE(fmt) (((fmt ^ IMGFMT_420P16_LE) & 0xff0000ff) == 0)
+#define IMGFMT_IS_YUVP16_BE(fmt) (((fmt ^ IMGFMT_420P16_BE) & 0xff0000ff) == 0)
+#define IMGFMT_IS_YUVP16_NE(fmt) (((fmt ^ IMGFMT_420P16 ) & 0xff0000ff) == 0)
+#define IMGFMT_IS_YUVP16(fmt) (IMGFMT_IS_YUVP16_LE(fmt) || IMGFMT_IS_YUVP16_BE(fmt))
+
/* Packed YUV Formats */
#define IMGFMT_IUYV 0x56595549
@@ -133,4 +158,11 @@ typedef struct {
const char *vo_format_name(int format);
+/**
+ * Calculates the scale shifts for the chroma planes for planar YUV
+ *
+ * \return bits-per-pixel for format if successful (i.e. format is 3 or 4-planes planar YUV), 0 otherwise
+ */
+int mp_get_chroma_shift(int format, int *x_shift, int *y_shift);
+
#endif /* MPLAYER_IMG_FORMAT_H */
diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c
index 3eb524d491..1bc0492e9c 100644
--- a/libmpcodecs/mp_image.c
+++ b/libmpcodecs/mp_image.c
@@ -14,37 +14,50 @@
#include "libvo/fastmemcpy.h"
-mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) {
- mp_image_t* mpi = new_mp_image(w,h);
-
- mp_image_setfmt(mpi,fmt);
+void mp_image_alloc_planes(mp_image_t *mpi) {
// IF09 - allocate space for 4. plane delta info - unused
- if (mpi->imgfmt == IMGFMT_IF09)
- {
- mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8+
- mpi->chroma_width*mpi->chroma_height);
- /* delta table, just for fun ;) */
- mpi->planes[3]=mpi->planes[0]+2*(mpi->chroma_width*mpi->chroma_height);
- }
- else
+ if (mpi->imgfmt == IMGFMT_IF09) {
+ mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8+
+ mpi->chroma_width*mpi->chroma_height);
+ } else
mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8);
- if(mpi->flags&MP_IMGFLAG_PLANAR){
+ if (mpi->flags&MP_IMGFLAG_PLANAR) {
+ int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1;
// YV12/I420/YVU9/IF09. feel free to add other planar formats here...
- if(!mpi->stride[0]) mpi->stride[0]=mpi->width;
- if(!mpi->stride[1]) mpi->stride[1]=mpi->stride[2]=mpi->chroma_width;
- if(mpi->flags&MP_IMGFLAG_SWAPPED){
- // I420/IYUV (Y,U,V)
- mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height;
- mpi->planes[2]=mpi->planes[1]+mpi->chroma_width*mpi->chroma_height;
+ mpi->stride[0]=mpi->stride[3]=bpp*mpi->width;
+ if(mpi->num_planes > 2){
+ mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width;
+ if(mpi->flags&MP_IMGFLAG_SWAPPED){
+ // I420/IYUV (Y,U,V)
+ mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
+ mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
+ if (mpi->num_planes > 3)
+ mpi->planes[3]=mpi->planes[2]+mpi->stride[2]*mpi->chroma_height;
+ } else {
+ // YV12,YVU9,IF09 (Y,V,U)
+ mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height;
+ mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height;
+ if (mpi->num_planes > 3)
+ mpi->planes[3]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
+ }
} else {
- // YV12,YVU9,IF09 (Y,V,U)
- mpi->planes[2]=mpi->planes[0]+mpi->width*mpi->height;
- mpi->planes[1]=mpi->planes[2]+mpi->chroma_width*mpi->chroma_height;
+ // NV12/NV21
+ mpi->stride[1]=mpi->chroma_width;
+ mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
}
} else {
- if(!mpi->stride[0]) mpi->stride[0]=mpi->width*mpi->bpp/8;
+ mpi->stride[0]=mpi->width*mpi->bpp/8;
+ if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
+ mpi->planes[1] = memalign(64, 1024);
}
mpi->flags|=MP_IMGFLAG_ALLOCATED;
+}
+
+mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) {
+ mp_image_t* mpi = new_mp_image(w,h);
+
+ mp_image_setfmt(mpi,fmt);
+ mp_image_alloc_planes(mpi);
return mpi;
}
diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h
index a62f403e27..667c131719 100644
--- a/libmpcodecs/mp_image.h
+++ b/libmpcodecs/mp_image.h
@@ -133,51 +133,32 @@ static inline void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){
}
mpi->flags|=MP_IMGFLAG_YUV;
mpi->num_planes=3;
+ if (mp_get_chroma_shift(out_fmt, NULL, NULL)) {
+ mpi->flags|=MP_IMGFLAG_PLANAR;
+ mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift);
+ mpi->chroma_width = mpi->width >> mpi->chroma_x_shift;
+ mpi->chroma_height = mpi->height >> mpi->chroma_y_shift;
+ }
switch(out_fmt){
case IMGFMT_I420:
case IMGFMT_IYUV:
mpi->flags|=MP_IMGFLAG_SWAPPED;
case IMGFMT_YV12:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=12;
- mpi->chroma_width=(mpi->width>>1);
- mpi->chroma_height=(mpi->height>>1);
- mpi->chroma_x_shift=1;
- mpi->chroma_y_shift=1;
return;
+ case IMGFMT_420A:
case IMGFMT_IF09:
mpi->num_planes=4;
case IMGFMT_YVU9:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=9;
- mpi->chroma_width=(mpi->width>>2);
- mpi->chroma_height=(mpi->height>>2);
- mpi->chroma_x_shift=2;
- mpi->chroma_y_shift=2;
- return;
case IMGFMT_444P:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=24;
- mpi->chroma_width=(mpi->width);
- mpi->chroma_height=(mpi->height);
- mpi->chroma_x_shift=0;
- mpi->chroma_y_shift=0;
- return;
case IMGFMT_422P:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=16;
- mpi->chroma_width=(mpi->width>>1);
- mpi->chroma_height=(mpi->height);
- mpi->chroma_x_shift=1;
- mpi->chroma_y_shift=0;
- return;
case IMGFMT_411P:
- mpi->flags|=MP_IMGFLAG_PLANAR;
- mpi->bpp=12;
- mpi->chroma_width=(mpi->width>>2);
- mpi->chroma_height=(mpi->height);
- mpi->chroma_x_shift=2;
- mpi->chroma_y_shift=0;
+ case IMGFMT_440P:
+ case IMGFMT_444P16_LE:
+ case IMGFMT_444P16_BE:
+ case IMGFMT_422P16_LE:
+ case IMGFMT_422P16_BE:
+ case IMGFMT_420P16_LE:
+ case IMGFMT_420P16_BE:
return;
case IMGFMT_Y800:
case IMGFMT_Y8:
@@ -230,6 +211,7 @@ static inline void free_mp_image(mp_image_t* mpi){
}
mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt);
+void mp_image_alloc_planes(mp_image_t *mpi);
void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi);
#endif /* MPLAYER_MP_IMAGE_H */
diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c
index a89e0a4dbe..9b833dac72 100644
--- a/libmpcodecs/vd_ffmpeg.c
+++ b/libmpcodecs/vd_ffmpeg.c
@@ -579,6 +579,7 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){
pic->data[0]= mpi->planes[0];
pic->data[1]= mpi->planes[1];
pic->data[2]= mpi->planes[2];
+ pic->data[3]= mpi->planes[3];
#if 0
assert(mpi->width >= ((width +align)&(~align)));
@@ -603,6 +604,7 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){
pic->linesize[0]= mpi->stride[0];
pic->linesize[1]= mpi->stride[1];
pic->linesize[2]= mpi->stride[2];
+ pic->linesize[3]= mpi->stride[3];
pic->opaque = mpi;
//printf("%X\n", (int)mpi->planes[0]);
@@ -837,9 +839,11 @@ static struct mp_image *decode(struct sh_video *sh, void *data, int len,
mpi->planes[0]=pic->data[0];
mpi->planes[1]=pic->data[1];
mpi->planes[2]=pic->data[2];
+ mpi->planes[3]=pic->data[3];
mpi->stride[0]=pic->linesize[0];
mpi->stride[1]=pic->linesize[1];
mpi->stride[2]=pic->linesize[2];
+ mpi->stride[3]=pic->linesize[3];
}
if (!mpi->planes[0])
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index 3c1c5e9538..d753d3d68a 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -379,46 +379,9 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype,
}
}
- // IF09 - allocate space for 4. plane delta info - unused
- if (mpi->imgfmt == IMGFMT_IF09)
- {
- mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8+
- mpi->chroma_width*mpi->chroma_height);
- /* export delta table */
- mpi->planes[3]=mpi->planes[0]+(mpi->width*mpi->height)+2*(mpi->chroma_width*mpi->chroma_height);
- }
- else
- mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8);
- if(mpi->flags&MP_IMGFLAG_PLANAR){
- // YV12/I420/YVU9/IF09. feel free to add other planar formats here...
- //if(!mpi->stride[0])
- mpi->stride[0]=mpi->width;
- //if(!mpi->stride[1])
- if(mpi->num_planes > 2){
- mpi->stride[1]=mpi->stride[2]=mpi->chroma_width;
- if(mpi->flags&MP_IMGFLAG_SWAPPED){
- // I420/IYUV (Y,U,V)
- mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height;
- mpi->planes[2]=mpi->planes[1]+mpi->chroma_width*mpi->chroma_height;
- } else {
- // YV12,YVU9,IF09 (Y,V,U)
- mpi->planes[2]=mpi->planes[0]+mpi->width*mpi->height;
- mpi->planes[1]=mpi->planes[2]+mpi->chroma_width*mpi->chroma_height;
- }
- } else {
- // NV12/NV21
- mpi->stride[1]=mpi->chroma_width;
- mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height;
- }
- } else {
- //if(!mpi->stride[0])
- mpi->stride[0]=mpi->width*mpi->bpp/8;
- if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
- mpi->planes[1] = memalign(64, 1024);
- }
+ mp_image_alloc_planes(mpi);
// printf("clearing img!\n");
vf_mpi_clear(mpi,0,0,mpi->width,mpi->height);
- mpi->flags|=MP_IMGFLAG_ALLOCATED;
}
}
if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c
index 3a1bae77c8..246624ae3a 100644
--- a/libmpcodecs/vf_scale.c
+++ b/libmpcodecs/vf_scale.c
@@ -49,9 +49,16 @@ void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, Sw
static const unsigned int outfmt_list[]={
// YUV:
IMGFMT_444P,
+ IMGFMT_444P16_LE,
+ IMGFMT_444P16_BE,
IMGFMT_422P,
+ IMGFMT_422P16_LE,
+ IMGFMT_422P16_BE,
IMGFMT_YV12,
IMGFMT_I420,
+ IMGFMT_420P16_LE,
+ IMGFMT_420P16_BE,
+ IMGFMT_420A,
IMGFMT_IYUV,
IMGFMT_YVU9,
IMGFMT_IF09,
@@ -60,6 +67,7 @@ static const unsigned int outfmt_list[]={
IMGFMT_NV21,
IMGFMT_YUY2,
IMGFMT_UYVY,
+ IMGFMT_440P,
// RGB and grayscale (Y8 and Y800):
IMGFMT_BGR32,
IMGFMT_RGB32,
@@ -322,7 +330,7 @@ static void start_slice(struct vf_instance* vf, mp_image_t *mpi){
static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src[MP_MAX_PLANES], int src_stride[MP_MAX_PLANES],
int y, int h, uint8_t *dst[MP_MAX_PLANES], int dst_stride[MP_MAX_PLANES], int interlaced){
- uint8_t *src2[MP_MAX_PLANES]={src[0], src[1], src[2]};
+ uint8_t *src2[MP_MAX_PLANES]={src[0], src[1], src[2], src[3]};
#if HAVE_BIGENDIAN
uint32_t pal2[256];
if (src[1] && !src[2]){
@@ -335,12 +343,12 @@ static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src
if(interlaced){
int i;
- uint8_t *dst2[MP_MAX_PLANES]={dst[0], dst[1], dst[2]};
- int src_stride2[MP_MAX_PLANES]={2*src_stride[0], 2*src_stride[1], 2*src_stride[2]};
- int dst_stride2[MP_MAX_PLANES]={2*dst_stride[0], 2*dst_stride[1], 2*dst_stride[2]};
+ uint8_t *dst2[MP_MAX_PLANES]={dst[0], dst[1], dst[2], dst[3]};
+ int src_stride2[MP_MAX_PLANES]={2*src_stride[0], 2*src_stride[1], 2*src_stride[2], 2*src_stride[3]};
+ int dst_stride2[MP_MAX_PLANES]={2*dst_stride[0], 2*dst_stride[1], 2*dst_stride[2], 2*dst_stride[3]};
sws_scale_ordered(sws1, src2, src_stride2, y>>1, h>>1, dst2, dst_stride2);
- for(i=0; i<3; i++){
+ for(i=0; i<MP_MAX_PLANES; i++){
src2[i] += src_stride[i];
dst2[i] += dst_stride[i];
}
@@ -471,6 +479,14 @@ static int query_format(struct vf_instance* vf, unsigned int fmt){
case IMGFMT_444P:
case IMGFMT_422P:
case IMGFMT_411P:
+ case IMGFMT_440P:
+ case IMGFMT_420A:
+ case IMGFMT_444P16_LE:
+ case IMGFMT_444P16_BE:
+ case IMGFMT_422P16_LE:
+ case IMGFMT_422P16_BE:
+ case IMGFMT_420P16_LE:
+ case IMGFMT_420P16_BE:
case IMGFMT_BGR8:
case IMGFMT_RGB8:
case IMGFMT_BG4B:
diff --git a/libvo/csputils.c b/libvo/csputils.c
new file mode 100644
index 0000000000..6f69ec4212
--- /dev/null
+++ b/libvo/csputils.c
@@ -0,0 +1,160 @@
+/*
+ * Common code related to colorspaces and conversion
+ *
+ * Copyleft (C) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
+ *
+ * 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 <stdint.h>
+#include <math.h>
+#include "libavutil/common.h"
+#include "csputils.h"
+
+/**
+ * \brief little helper function to create a lookup table for gamma
+ * \param map buffer to create map into
+ * \param size size of buffer
+ * \param gamma gamma value
+ */
+void mp_gen_gamma_map(uint8_t *map, int size, float gamma) {
+ int i;
+ if (gamma == 1.0) {
+ for (i = 0; i < size; i++)
+ map[i] = 255 * i / (size - 1);
+ return;
+ }
+ gamma = 1.0 / gamma;
+ for (i = 0; i < size; i++) {
+ float tmp = (float)i / (size - 1.0);
+ tmp = pow(tmp, gamma);
+ if (tmp > 1.0) tmp = 1.0;
+ if (tmp < 0.0) tmp = 0.0;
+ map[i] = 255 * tmp;
+ }
+}
+
+/**
+ * \brief get the coefficients of the yuv -> rgb conversion matrix
+ * \param params struct specifying the properties of the conversion like brightness, ...
+ * \param yuv2rgb array to store coefficients into
+ *
+ * Note: contrast, hue and saturation will only work as expected with YUV formats,
+ * not with e.g. MP_CSP_XYZ
+ */
+void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]) {
+ float uvcos = params->saturation * cos(params->hue);
+ float uvsin = params->saturation * sin(params->hue);
+ int format = params->format;
+ int i;
+ const float (*uv_coeffs)[3];
+ const float *level_adjust;
+ static const float yuv_pc_level_adjust[4] = {-16 / 255.0, -128 / 255.0, -128 / 255.0, 1.164};
+ static const float yuv_tv_level_adjust[4] = {0, -128 / 255.0, -128 / 255.0, 0};
+ static const float xyz_level_adjust[4] = {0, 0, 0, 0};
+ static const float uv_coeffs_table[MP_CSP_COUNT][3][3] = {
+ [MP_CSP_DEFAULT] = {
+ {1, 0.000, 1.596},
+ {1, -0.391, -0.813},
+ {1, 2.018, 0.000}
+ },
+ [MP_CSP_BT_601] = {
+ {1, 0.000, 1.403},
+ {1, -0.344, -0.714},
+ {1, 1.773, 0.000}
+ },
+ [MP_CSP_BT_709] = {
+ {1, 0.0000, 1.5701},
+ {1, -0.1870, -0.4664},
+ {1, 1.8556, 0.0000}
+ },
+ [MP_CSP_SMPTE_240M] = {
+ {1, 0.0000, 1.5756},
+ {1, -0.2253, -0.5000},
+ {1, 1.8270, 0.0000}
+ },
+ [MP_CSP_EBU] = {
+ {1, 0.000, 1.140},
+ {1, -0.396, -0.581},
+ {1, 2.029, 0.000}
+ },
+ [MP_CSP_XYZ] = {
+ { 3.2404542, -1.5371385, -0.4985314},
+ {-0.9692660, 1.8760108, 0.0415560},
+ { 0.0556434, -0.2040259, 1.0572252}
+ },
+ };
+
+ if (format < 0 || format >= MP_CSP_COUNT)
+ format = MP_CSP_DEFAULT;
+ uv_coeffs = uv_coeffs_table[format];
+ level_adjust = yuv_pc_level_adjust;
+ if (format == MP_CSP_XYZ)
+ level_adjust = xyz_level_adjust;
+
+ for (i = 0; i < 3; i++) {
+ yuv2rgb[i][COL_C] = params->brightness;
+ yuv2rgb[i][COL_Y] = uv_coeffs[i][COL_Y] * level_adjust[COL_C] * params->contrast;
+ yuv2rgb[i][COL_C] += level_adjust[COL_Y] * yuv2rgb[i][COL_Y];
+ yuv2rgb[i][COL_U] = uv_coeffs[i][COL_U] * uvcos + uv_coeffs[i][COL_V] * uvsin;
+ yuv2rgb[i][COL_C] += level_adjust[COL_U] * yuv2rgb[i][COL_U];
+ yuv2rgb[i][COL_V] = uv_coeffs[i][COL_U] * uvsin + uv_coeffs[i][COL_V] * uvcos;
+ yuv2rgb[i][COL_C] += level_adjust[COL_V] * yuv2rgb[i][COL_V];
+ // this "centers" contrast control so that e.g. a contrast of 0
+ // leads to a grey image, not a black one
+ yuv2rgb[i][COL_C] += 0.5 - params->contrast / 2.0;
+ }
+}
+
+//! size of gamma map use to avoid slow exp function in gen_yuv2rgb_map
+#define GMAP_SIZE (1024)
+/**
+ * \brief generate a 3D YUV -> RGB map
+ * \param params struct containing parameters like brightness, gamma, ...
+ * \param map where to store map. Must provide space for (size + 2)^3 elements
+ * \param size size of the map, excluding border
+ */
+void mp_gen_yuv2rgb_map(struct mp_csp_params *params, unsigned char *map, int size) {
+ int i, j, k, l;
+ float step = 1.0 / size;
+ float y, u, v;
+ float yuv2rgb[3][4];
+ unsigned char gmaps[3][GMAP_SIZE];
+ mp_gen_gamma_map(gmaps[0], GMAP_SIZE, params->rgamma);
+ mp_gen_gamma_map(gmaps[1], GMAP_SIZE, params->ggamma);
+ mp_gen_gamma_map(gmaps[2], GMAP_SIZE, params->bgamma);
+ mp_get_yuv2rgb_coeffs(params, yuv2rgb);
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 4; j++)
+ yuv2rgb[i][j] *= GMAP_SIZE - 1;
+ v = 0;
+ for (i = -1; i <= size; i++) {
+ u = 0;
+ for (j = -1; j <= size; j++) {
+ y = 0;
+ for (k = -1; k <= size; k++) {
+ for (l = 0; l < 3; l++) {
+ float rgb = yuv2rgb[l][COL_Y] * y + yuv2rgb[l][COL_U] * u + yuv2rgb[l][COL_V] * v + yuv2rgb[l][COL_C];
+ *map++ = gmaps[l][av_clip(rgb, 0, GMAP_SIZE - 1)];
+ }
+ y += (k == -1 || k == size - 1) ? step / 2 : step;
+ }
+ u += (j == -1 || j == size - 1) ? step / 2 : step;
+ }
+ v += (i == -1 || i == size - 1) ? step / 2 : step;
+ }
+}
diff --git a/libvo/csputils.h b/libvo/csputils.h
new file mode 100644
index 0000000000..4723c7006d
--- /dev/null
+++ b/libvo/csputils.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_CSPUTILS_H
+#define MPLAYER_CSPUTILS_H
+
+#include <stdint.h>
+
+enum mp_csp_standard {
+ MP_CSP_DEFAULT,
+ MP_CSP_BT_601,
+ MP_CSP_BT_709,
+ MP_CSP_SMPTE_240M,
+ MP_CSP_EBU,
+ MP_CSP_XYZ,
+ MP_CSP_COUNT
+};
+
+struct mp_csp_params {
+ enum mp_csp_standard format;
+ float brightness;
+ float contrast;
+ float hue;
+ float saturation;
+ float rgamma;
+ float ggamma;
+ float bgamma;
+};
+
+void mp_gen_gamma_map(unsigned char *map, int size, float gamma);
+#define ROW_R 0
+#define ROW_G 1
+#define ROW_B 2
+#define COL_Y 0
+#define COL_U 1
+#define COL_V 2
+#define COL_C 3
+void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]);
+void mp_gen_yuv2rgb_map(struct mp_csp_params *params, uint8_t *map, int size);
+
+#endif /* MPLAYER_CSPUTILS_H */
diff --git a/libvo/gl_common.c b/libvo/gl_common.c
index 527c891327..b6bef7f1b7 100644
--- a/libvo/gl_common.c
+++ b/libvo/gl_common.c
@@ -34,7 +34,7 @@
#include <math.h>
#include "old_vo_defines.h"
#include "gl_common.h"
-#include "libavutil/common.h"
+#include "csputils.h"
void (GLAPIENTRY *Begin)(GLenum);
void (GLAPIENTRY *End)(void);
@@ -235,6 +235,16 @@ int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt,
if (!gl_format) gl_format = &dummy2;
if (!gl_type) gl_type = &dummy2;
+ if (mp_get_chroma_shift(fmt, NULL, NULL)) {
+ // reduce the possible cases a bit
+ if (IMGFMT_IS_YUVP16_LE(fmt))
+ fmt = IMGFMT_420P16_LE;
+ else if (IMGFMT_IS_YUVP16_BE(fmt))
+ fmt = IMGFMT_420P16_BE;
+ else
+ fmt = IMGFMT_YV12;
+ }
+
*bpp = IMGFMT_IS_BGR(fmt)?IMGFMT_BGR_DEPTH(fmt):IMGFMT_RGB_DEPTH(fmt);
*gl_texfmt = 3;
switch (fmt) {
@@ -251,6 +261,13 @@ int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt,
*gl_format = GL_RGBA;
*gl_type = GL_UNSIGNED_BYTE;
break;
+ case IMGFMT_420P16:
+ supported = 0; // no native YUV support
+ *gl_texfmt = 1;
+ *bpp = 16;
+ *gl_format = GL_LUMINANCE;
+ *gl_type = GL_UNSIGNED_SHORT;
+ break;
case IMGFMT_YV12:
supported = 0; // no native YV12 support
case IMGFMT_Y800:
@@ -1005,78 +1022,6 @@ static void create_scaler_textures(int scaler, int *texu, char *texs) {
}
}
-static void gen_gamma_map(unsigned char *map, int size, float gamma);
-
-#define ROW_R 0
-#define ROW_G 1
-#define ROW_B 2
-#define COL_Y 0
-#define COL_U 1
-#define COL_V 2
-#define COL_C 3
-
-static void get_yuv2rgb_coeffs(gl_conversion_params_t *params, float yuv2rgb[3][4]) {
- float uvcos = params->saturation * cos(params->hue);
- float uvsin = params->saturation * sin(params->hue);
- int i;
- float uv_coeffs[3][2] = {
- { 0.000, 1.596},
- {-0.391, -0.813},
- { 2.018, 0.000}
- };
- for (i = 0; i < 3; i++) {
- yuv2rgb[i][COL_C] = params->brightness;
- yuv2rgb[i][COL_Y] = 1.164 * params->contrast;
- yuv2rgb[i][COL_C] += (-16 / 255.0) * yuv2rgb[i][COL_Y];
- yuv2rgb[i][COL_U] = uv_coeffs[i][0] * uvcos + uv_coeffs[i][1] * uvsin;
- yuv2rgb[i][COL_C] += (-128 / 255.0) * yuv2rgb[i][COL_U];
- yuv2rgb[i][COL_V] = uv_coeffs[i][0] * uvsin + uv_coeffs[i][1] * uvcos;
- yuv2rgb[i][COL_C] += (-128 / 255.0) * yuv2rgb[i][COL_V];
- // this "centers" contrast control so that e.g. a contrast of 0
- // leads to a grey image, not a black one
- yuv2rgb[i][COL_C] += 0.5 - params->contrast / 2.0;
- }
-}
-
-//! size of gamma map use to avoid slow exp function in gen_yuv2rgb_map
-#define GMAP_SIZE (1024)
-/**
- * \brief generate a 3D YUV -> RGB map
- * \param params struct containing parameters like brightness, gamma, ...
- * \param map where to store map. Must provide space for (size + 2)^3 elements
- * \param size size of the map, excluding border
- */
-static void gen_yuv2rgb_map(gl_conversion_params_t *params, unsigned char *map, int size) {
- int i, j, k, l;
- float step = 1.0 / size;
- float y, u, v;
- float yuv2rgb[3][4];
- unsigned char gmaps[3][GMAP_SIZE];
- gen_gamma_map(gmaps[0], GMAP_SIZE, params->rgamma);
- gen_gamma_map(gmaps[1], GMAP_SIZE, params->ggamma);
- gen_gamma_map(gmaps[2], GMAP_SIZE, params->bgamma);
- get_yuv2rgb_coeffs(params, yuv2rgb);
- for (i = 0; i < 3; i++)
- for (j = 0; j < 4; j++)
- yuv2rgb[i][j] *= GMAP_SIZE - 1;
- v = 0;
- for (i = -1; i <= size; i++) {
- u = 0;
- for (j = -1; j <= size; j++) {
- y = 0;
- for (k = -1; k <= size; k++) {
- for (l = 0; l < 3; l++) {
- float rgb = yuv2rgb[l][COL_Y] * y + yuv2rgb[l][COL_U] * u + yuv2rgb[l][COL_V] * v + yuv2rgb[l][COL_C];
- *map++ = gmaps[l][av_clip(rgb, 0, GMAP_SIZE - 1)];
- }
- y += (k == -1 || k == size - 1) ? step / 2 : step;
- }
- u += (j == -1 || j == size - 1) ? step / 2 : step;
- }
- v += (i == -1 || i == size - 1) ? step / 2 : step;
- }
-}
-
//! resolution of texture for gamma lookup table
#define LOOKUP_RES 512
//! resolution for 3D yuv->rgb conversion lookup table
@@ -1098,9 +1043,9 @@ static void create_conv_textures(gl_conversion_params_t *params, int *texu, char
texs[0] = (*texu)++;
ActiveTexture(GL_TEXTURE0 + texs[0]);
lookup_data = malloc(4 * LOOKUP_RES);
- gen_gamma_map(lookup_data, LOOKUP_RES, params->rgamma);
- gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, params->ggamma);
- gen_gamma_map(&lookup_data[2 * LOOKUP_RES], LOOKUP_RES, params->bgamma);
+ mp_gen_gamma_map(lookup_data, LOOKUP_RES, params->csp_params.rgamma);
+ mp_gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, params->csp_params.ggamma);
+ mp_gen_gamma_map(&lookup_data[2 * LOOKUP_RES], LOOKUP_RES, params->csp_params.bgamma);
glCreateClearTex(GL_TEXTURE_2D, GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LINEAR,
LOOKUP_RES, 4, 0);
glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data,
@@ -1118,7 +1063,7 @@ static void create_conv_textures(gl_conversion_params_t *params, int *texu, char
texs[0] = (*texu)++;
ActiveTexture(GL_TEXTURE0 + texs[0]);
lookup_data = malloc(3 * sz * sz * sz);
- gen_yuv2rgb_map(params, lookup_data, LOOKUP_3DRES);
+ mp_gen_yuv2rgb_map(&params->csp_params, lookup_data, LOOKUP_3DRES);
glAdjustAlignment(sz);
PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
TexImage3D(GL_TEXTURE_3D, 0, 3, sz, sz, sz, 1,
@@ -1324,10 +1269,10 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) {
add_scaler(YUV_LUM_SCALER(type), &prog_pos, &prog_remain, lum_scale_texs,
'0', 'r', rect, texw, texh, params->filter_strength);
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
- '1', 'g', rect, texw / 2, texh / 2, params->filter_strength);
+ '1', 'g', rect, params->chrom_texw, params->chrom_texh, params->filter_strength);
add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs,
- '2', 'b', rect, texw / 2, texh / 2, params->filter_strength);
- get_yuv2rgb_coeffs(params, yuv2rgb);
+ '2', 'b', rect, params->chrom_texw, params->chrom_texh, params->filter_strength);
+ mp_get_yuv2rgb_coeffs(&params->csp_params, yuv2rgb);
switch (YUV_CONVERSION(type)) {
case YUV_CONVERSION_FRAGMENT:
snprintf(prog_pos, prog_remain, yuv_prog_template,
@@ -1342,7 +1287,7 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) {
yuv2rgb[ROW_R][COL_U], yuv2rgb[ROW_G][COL_U], yuv2rgb[ROW_B][COL_U],
yuv2rgb[ROW_R][COL_V], yuv2rgb[ROW_G][COL_V], yuv2rgb[ROW_B][COL_V],
yuv2rgb[ROW_R][COL_C], yuv2rgb[ROW_G][COL_C], yuv2rgb[ROW_B][COL_C],
- (float)1.0 / params->rgamma, (float)1.0 / params->bgamma, (float)1.0 / params->bgamma);
+ (float)1.0 / params->csp_params.rgamma, (float)1.0 / params->csp_params.bgamma, (float)1.0 / params->csp_params.bgamma);
break;
case YUV_CONVERSION_FRAGMENT_LOOKUP:
snprintf(prog_pos, prog_remain, yuv_lookup_prog_template,
@@ -1365,37 +1310,14 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) {
}
/**
- * \brief little helper function to create a lookup table for gamma
- * \param map buffer to create map into
- * \param size size of buffer
- * \param gamma gamma value
- */
-static void gen_gamma_map(unsigned char *map, int size, float gamma) {
- int i;
- if (gamma == 1.0) {
- for (i = 0; i < size; i++)
- map[i] = 255 * i / (size - 1);
- return;
- }
- gamma = 1.0 / gamma;
- for (i = 0; i < size; i++) {
- float tmp = (float)i / (size - 1.0);
- tmp = pow(tmp, gamma);
- if (tmp > 1.0) tmp = 1.0;
- if (tmp < 0.0) tmp = 0.0;
- map[i] = 255 * tmp;
- }
-}
-
-/**
* \brief setup YUV->RGB conversion
* \param parms struct containing parameters like conversion and scaler type,
* brightness, ...
* \ingroup glconversion
*/
void glSetupYUVConversion(gl_conversion_params_t *params) {
- float uvcos = params->saturation * cos(params->hue);
- float uvsin = params->saturation * sin(params->hue);
+ float uvcos = params->csp_params.saturation * cos(params->csp_params.hue);
+ float uvsin = params->csp_params.saturation * sin(params->csp_params.hue);
switch (YUV_CONVERSION(params->type)) {
case YUV_CONVERSION_COMBINERS:
glSetupYUVCombiners(uvcos, uvsin);
@@ -1497,14 +1419,19 @@ void glDisableYUVConversion(GLenum target, int type) {
* \param sx width of texture in pixels
* \param sy height of texture in pixels
* \param rect_tex whether this texture uses texture_rectangle extension
- * \param is_yv12 if set, also draw the textures from units 1 and 2
+ * \param is_yv12 if != 0, also draw the textures from units 1 and 2,
+ * bits 8 - 15 and 16 - 23 specify the x and y scaling of those textures
* \param flip flip the texture upside down
* \ingroup gltexture
*/
void glDrawTex(GLfloat x, GLfloat y, GLfloat w, GLfloat h,
GLfloat tx, GLfloat ty, GLfloat tw, GLfloat th,
int sx, int sy, int rect_tex, int is_yv12, int flip) {
- GLfloat tx2 = tx / 2, ty2 = ty / 2, tw2 = tw / 2, th2 = th / 2;
+ int chroma_x_shift = (is_yv12 >> 8) & 31;
+ int chroma_y_shift = (is_yv12 >> 16) & 31;
+ GLfloat xscale = 1 << chroma_x_shift;
+ GLfloat yscale = 1 << chroma_y_shift;
+ GLfloat tx2 = tx / xscale, ty2 = ty / yscale, tw2 = tw / xscale, th2 = th / yscale;
if (!rect_tex) {
tx /= sx; ty /= sy; tw /= sx; th /= sy;
tx2 = tx, ty2 = ty, tw2 = tw, th2 = th;
diff --git a/libvo/gl_common.h b/libvo/gl_common.h
index e556718ec0..db20ebbc65 100644
--- a/libvo/gl_common.h
+++ b/libvo/gl_common.h
@@ -26,6 +26,7 @@
#include "mp_msg.h"
#include "video_out.h"
+#include "csputils.h"
#ifdef CONFIG_GL_WIN32
#include <windows.h>
@@ -329,18 +330,15 @@ int loadGPUProgram(GLenum target, char *prog);
//! extract chrominance scaler out of type
#define YUV_CHROM_SCALER(t) ((t >> YUV_CHROM_SCALER_SHIFT) & YUV_SCALER_MASK)
/** \} */
+
typedef struct {
GLenum target;
int type;
- float brightness;
- float contrast;
- float hue;
- float saturation;
- float rgamma;
- float ggamma;
- float bgamma;
+ struct mp_csp_params csp_params;
int texw;
int texh;
+ int chrom_texw;
+ int chrom_texh;
float filter_strength;
} gl_conversion_params_t;
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 9a2aafac31..b0c3a1507c 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -90,6 +90,8 @@ static int use_ycbcr;
#define MASK_NOT_COMBINERS (~((1 << YUV_CONVERSION_NONE) | (1 << YUV_CONVERSION_COMBINERS) | (1 << YUV_CONVERSION_COMBINERS_ATI)))
#define MASK_GAMMA_SUPPORT (MASK_NOT_COMBINERS & ~(1 << YUV_CONVERSION_FRAGMENT))
static int use_yuv;
+static int colorspace;
+static int is_yuv;
static int lscale;
static int cscale;
static float filter_strength;
@@ -203,6 +205,7 @@ static void texSize(int w, int h, int *texw, int *texh) {
//! maximum size of custom fragment program
#define MAX_CUSTOM_PROG_SIZE (1024 * 1024)
static void update_yuvconv(void) {
+ int xs, ys;
float bri = eq_bri / 100.0;
float cont = (eq_cont + 100) / 100.0;
float hue = eq_hue / 100.0 * 3.1415927;
@@ -211,8 +214,11 @@ static void update_yuvconv(void) {
float ggamma = exp(log(8.0) * eq_ggamma / 100.0);
float bgamma = exp(log(8.0) * eq_bgamma / 100.0);
gl_conversion_params_t params = {gl_target, yuvconvtype,
- bri, cont, hue, sat, rgamma, ggamma, bgamma,
- texture_width, texture_height, filter_strength};
+ {colorspace, bri, cont, hue, sat, rgamma, ggamma, bgamma},
+ texture_width, texture_height, 0, 0, filter_strength};
+ mp_get_chroma_shift(image_format, &xs, &ys);
+ params.chrom_texw = params.texw >> xs;
+ params.chrom_texh = params.texh >> ys;
glSetupYUVConversion(&params);
if (custom_prog) {
FILE *f = fopen(custom_prog, "r");
@@ -475,8 +481,10 @@ static int initGl(uint32_t d_width, uint32_t d_height) {
mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",
texture_width, texture_height);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
int i;
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
GenTextures(21, default_texs);
default_texs[21] = 0;
for (i = 0; i < 7; i++) {
@@ -487,18 +495,18 @@ static int initGl(uint32_t d_width, uint32_t d_height) {
}
ActiveTexture(GL_TEXTURE1);
glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
if (mipmap_gen)
TexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE);
ActiveTexture(GL_TEXTURE2);
glCreateClearTex(gl_target, gl_texfmt, gl_format, gl_type, scale_type,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
if (mipmap_gen)
TexParameteri(gl_target, GL_GENERATE_MIPMAP, GL_TRUE);
ActiveTexture(GL_TEXTURE0);
BindTexture(gl_target, 0);
}
- if (image_format == IMGFMT_YV12 || custom_prog)
+ if (is_yuv || custom_prog)
{
if ((MASK_NOT_COMBINERS & (1 << use_yuv)) || custom_prog) {
if (!GenPrograms || !BindProgram) {
@@ -530,9 +538,12 @@ static int initGl(uint32_t d_width, uint32_t d_height) {
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)
{
+ int xs, ys;
image_height = height;
image_width = width;
image_format = format;
+ is_yuv = mp_get_chroma_shift(image_format, &xs, &ys) > 0;
+ is_yuv |= (xs << 8) | (ys << 16);
glFindFormat(format, NULL, &gl_texfmt, &gl_format, &gl_type);
vo_flipped = !!(flags & VOFLAG_FLIPPING);
@@ -701,14 +712,14 @@ static void do_render(void) {
// BindTexture(GL_TEXTURE_2D, texture_id);
Color3f(1,1,1);
- if (image_format == IMGFMT_YV12 || custom_prog)
+ if (is_yuv || custom_prog)
glEnableYUVConversion(gl_target, yuvconvtype);
glDrawTex(0, 0, image_width, image_height,
0, 0, image_width, image_height,
texture_width, texture_height,
- use_rectangle == 1, image_format == IMGFMT_YV12,
+ use_rectangle == 1, is_yuv,
mpi_flipped ^ vo_flipped);
- if (image_format == IMGFMT_YV12 || custom_prog)
+ if (is_yuv || custom_prog)
glDisableYUVConversion(gl_target, yuvconvtype);
}
@@ -737,13 +748,15 @@ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
mpi_flipped = stride[0] < 0;
glUploadTex(gl_target, gl_format, gl_type, src[0], stride[0],
x, y, w, h, slice_height);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
ActiveTexture(GL_TEXTURE1);
glUploadTex(gl_target, gl_format, gl_type, src[1], stride[1],
- x / 2, y / 2, w / 2, h / 2, slice_height);
+ x >> xs, y >> ys, w >> xs, h >> ys, slice_height);
ActiveTexture(GL_TEXTURE2);
glUploadTex(gl_target, gl_format, gl_type, src[2], stride[2],
- x / 2, y / 2, w / 2, h / 2, slice_height);
+ x >> xs, y >> ys, w >> xs, h >> ys, slice_height);
ActiveTexture(GL_TEXTURE0);
}
return 0;
@@ -801,14 +814,16 @@ static uint32_t get_image(mp_image_t *mpi) {
err_shown = 1;
return VO_FALSE;
}
- if (mpi->imgfmt == IMGFMT_YV12) {
- // YV12
+ if (is_yuv) {
+ // planar YUV
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
mpi->flags |= MP_IMGFLAG_COMMON_STRIDE | MP_IMGFLAG_COMMON_PLANE;
mpi->stride[0] = mpi->width;
mpi->planes[1] = mpi->planes[0] + mpi->stride[0] * mpi->height;
- mpi->stride[1] = mpi->width >> 1;
- mpi->planes[2] = mpi->planes[1] + mpi->stride[1] * (mpi->height >> 1);
- mpi->stride[2] = mpi->width >> 1;
+ mpi->stride[1] = mpi->width >> xs;
+ mpi->planes[2] = mpi->planes[1] + mpi->stride[1] * (mpi->height >> ys);
+ mpi->stride[2] = mpi->width >> xs;
if (ati_hack && !mesa_buffer) {
mpi->flags &= ~MP_IMGFLAG_COMMON_PLANE;
if (!gl_buffer_uv[0]) GenBuffers(2, gl_buffer_uv);
@@ -858,17 +873,19 @@ static uint32_t draw_image(mp_image_t *mpi) {
mpi2.flags = 0; mpi2.type = MP_IMGTYPE_TEMP;
mpi2.width = mpi2.w; mpi2.height = mpi2.h;
if (force_pbo && !(mpi->flags & MP_IMGFLAG_DIRECT) && !gl_bufferptr && get_image(&mpi2) == VO_TRUE) {
- int bpp = mpi->imgfmt == IMGFMT_YV12 ? 8 : mpi->bpp;
+ int bpp = is_yuv ? 8 : mpi->bpp;
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
memcpy_pic(mpi2.planes[0], mpi->planes[0], mpi->w * bpp / 8, mpi->h, mpi2.stride[0], mpi->stride[0]);
- if (mpi->imgfmt == IMGFMT_YV12) {
- memcpy_pic(mpi2.planes[1], mpi->planes[1], mpi->w >> 1, mpi->h >> 1, mpi2.stride[1], mpi->stride[1]);
- memcpy_pic(mpi2.planes[2], mpi->planes[2], mpi->w >> 1, mpi->h >> 1, mpi2.stride[2], mpi->stride[2]);
+ if (is_yuv) {
+ memcpy_pic(mpi2.planes[1], mpi->planes[1], mpi->w >> xs, mpi->h >> ys, mpi2.stride[1], mpi->stride[1]);
+ memcpy_pic(mpi2.planes[2], mpi->planes[2], mpi->w >> xs, mpi->h >> ys, mpi2.stride[2], mpi->stride[2]);
}
if (ati_hack) { // since we have to do a full upload we need to clear the borders
clear_border(mpi2.planes[0], mpi->w * bpp / 8, mpi2.stride[0], mpi->h, mpi2.height, 0);
- if (mpi->imgfmt == IMGFMT_YV12) {
- clear_border(mpi2.planes[1], mpi->w >> 1, mpi2.stride[1], mpi->h >> 1, mpi2.height >> 1, 128);
- clear_border(mpi2.planes[2], mpi->w >> 1, mpi2.stride[2], mpi->h >> 1, mpi2.height >> 1, 128);
+ if (is_yuv) {
+ clear_border(mpi2.planes[1], mpi->w >> xs, mpi2.stride[1], mpi->h >> ys, mpi2.height >> ys, 128);
+ clear_border(mpi2.planes[2], mpi->w >> xs, mpi2.stride[2], mpi->h >> ys, mpi2.height >> ys, 128);
}
}
mpi = &mpi2;
@@ -898,7 +915,9 @@ static uint32_t draw_image(mp_image_t *mpi) {
}
glUploadTex(gl_target, gl_format, gl_type, planes[0], stride[0],
mpi->x, mpi->y, w, h, slice);
- if (mpi->imgfmt == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
if ((mpi->flags & MP_IMGFLAG_DIRECT) && !(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) {
BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[0]);
UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@@ -906,7 +925,7 @@ static uint32_t draw_image(mp_image_t *mpi) {
}
ActiveTexture(GL_TEXTURE1);
glUploadTex(gl_target, gl_format, gl_type, planes[1], stride[1],
- mpi->x / 2, mpi->y / 2, w / 2, h / 2, slice);
+ mpi->x >> xs, mpi->y >> ys, w >> xs, h >> ys, slice);
if ((mpi->flags & MP_IMGFLAG_DIRECT) && !(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) {
BindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[1]);
UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@@ -914,7 +933,7 @@ static uint32_t draw_image(mp_image_t *mpi) {
}
ActiveTexture(GL_TEXTURE2);
glUploadTex(gl_target, gl_format, gl_type, planes[2], stride[2],
- mpi->x / 2, mpi->y / 2, w / 2, h / 2, slice);
+ mpi->x >> xs, mpi->y >> ys, w >> xs, h >> ys, slice);
ActiveTexture(GL_TEXTURE0);
}
if (mpi->flags & MP_IMGFLAG_DIRECT) {
@@ -942,7 +961,8 @@ query_format(uint32_t format)
caps |= VFCAP_OSD | VFCAP_EOSD | (scaled_osd ? 0 : VFCAP_EOSD_UNSCALED);
if (format == IMGFMT_RGB24 || format == IMGFMT_RGBA)
return caps;
- if (use_yuv && format == IMGFMT_YV12)
+ if (use_yuv && mp_get_chroma_shift(format, NULL, NULL) &&
+ (IMGFMT_IS_YUVP16_NE(format) || !IMGFMT_IS_YUVP16(format)))
return caps;
// HACK, otherwise we get only b&w with some filters (e.g. -vf eq)
// ideally MPlayer should be fixed instead not to use Y800 when it has the choice
@@ -969,17 +989,24 @@ uninit(void)
uninit_mpglcontext(&glctx);
}
+static int valid_csp(void *p)
+{
+ int *csp = p;
+ return *csp >= -1 && *csp < MP_CSP_COUNT;
+}
+
static const opt_t subopts[] = {
{"manyfmts", OPT_ARG_BOOL, &many_fmts, NULL},
{"osd", OPT_ARG_BOOL, &use_osd, NULL},
{"scaled-osd", OPT_ARG_BOOL, &scaled_osd, NULL},
{"aspect", OPT_ARG_BOOL, &use_aspect, NULL},
{"ycbcr", OPT_ARG_BOOL, &use_ycbcr, NULL},
- {"slice-height", OPT_ARG_INT, &slice_height, (opt_test_f)int_non_neg},
- {"rectangle", OPT_ARG_INT, &use_rectangle,(opt_test_f)int_non_neg},
- {"yuv", OPT_ARG_INT, &use_yuv, (opt_test_f)int_non_neg},
- {"lscale", OPT_ARG_INT, &lscale, (opt_test_f)int_non_neg},
- {"cscale", OPT_ARG_INT, &cscale, (opt_test_f)int_non_neg},
+ {"slice-height", OPT_ARG_INT, &slice_height, int_non_neg},
+ {"rectangle", OPT_ARG_INT, &use_rectangle,int_non_neg},
+ {"yuv", OPT_ARG_INT, &use_yuv, int_non_neg},
+ {"colorspace", OPT_ARG_INT, &colorspace, valid_csp},
+ {"lscale", OPT_ARG_INT, &lscale, int_non_neg},
+ {"cscale", OPT_ARG_INT, &cscale, int_non_neg},
{"filter-strength", OPT_ARG_FLOAT, &filter_strength, NULL},
{"ati-hack", OPT_ARG_BOOL, &ati_hack, NULL},
{"force-pbo", OPT_ARG_BOOL, &force_pbo, NULL},
@@ -1008,6 +1035,7 @@ static int preinit(const char *arg)
use_aspect = 1;
use_ycbcr = 0;
use_yuv = 0;
+ colorspace = -1;
lscale = 0;
cscale = 0;
filter_strength = 0.5;
@@ -1063,6 +1091,13 @@ static int preinit(const char *arg)
" 4: use fragment program with gamma correction via lookup.\n"
" 5: use ATI-specific method (for older cards).\n"
" 6: use lookup via 3D texture.\n"
+ " colorspace=<n>\n"
+ " 0: MPlayer's default YUV to RGB conversion\n"
+ " 1: YUV to RGB according to BT.601\n"
+ " 2: YUV to RGB according to BT.709\n"
+ " 3: YUV to RGB according to SMPT-240M\n"
+ " 4: YUV to RGB according to EBU\n"
+ " 5: XYZ to RGB\n"
" lscale=<n>\n"
" 0: use standard bilinear scaling for luma.\n"
" 1: use improved bicubic scaling for luma.\n"
@@ -1170,7 +1205,7 @@ static int control(uint32_t request, void *data)
resize(vo_dwidth, vo_dheight);
return VO_TRUE;
case VOCTRL_GET_EQUALIZER:
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
struct voctrl_get_equalizer_args *args = data;
int i;
for (i = 0; eq_map[i].name; i++)
@@ -1182,7 +1217,7 @@ static int control(uint32_t request, void *data)
}
break;
case VOCTRL_SET_EQUALIZER:
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
struct voctrl_set_equalizer_args *args = data;
int i;
for (i = 0; eq_map[i].name; i++)
diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c
index 73c09364f7..f1f69f3de2 100644
--- a/libvo/vo_gl2.c
+++ b/libvo/vo_gl2.c
@@ -85,6 +85,7 @@ static int isGL12 = GL_FALSE;
static int gl_bilinear=1;
static int gl_antialias=0;
static int use_yuv;
+static int is_yuv;
static int use_glFinish;
static void (*draw_alpha_fnc)
@@ -181,7 +182,7 @@ static int initTextures(void)
s*=2;
texture_height=s;
- if (image_format != IMGFMT_YV12)
+ if (!is_yuv)
gl_internal_format = getInternalFormat();
/* Test the max texture size */
@@ -260,7 +261,7 @@ static int initTextures(void)
glGenTextures (1, &(tsq->texobj));
glBindTexture (GL_TEXTURE_2D, tsq->texobj);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
glGenTextures(2, tsq->uvtexobjs);
ActiveTexture(GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[0]);
@@ -273,13 +274,15 @@ static int initTextures(void)
texture_width, texture_height, 0);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
ActiveTexture(GL_TEXTURE1);
glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
ActiveTexture(GL_TEXTURE2);
glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR,
- texture_width / 2, texture_height / 2, 128);
+ texture_width >> xs, texture_height >> ys, 128);
ActiveTexture(GL_TEXTURE0);
}
@@ -378,7 +381,7 @@ static void drawTextureDisplay (void)
glColor3f(1.0,1.0,1.0);
- if (image_format == IMGFMT_YV12)
+ if (is_yuv)
glEnableYUVConversion(GL_TEXTURE_2D, use_yuv);
for (y = 0; y < texnumy; y++) {
int thish = texture_height;
@@ -389,7 +392,7 @@ static void drawTextureDisplay (void)
if (x == texnumx - 1 && image_width % texture_width)
thisw = image_width % texture_width;
glBindTexture (GL_TEXTURE_2D, square->texobj);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
ActiveTexture(GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[0]);
ActiveTexture(GL_TEXTURE2);
@@ -406,11 +409,11 @@ static void drawTextureDisplay (void)
glDrawTex(square->fx, square->fy, square->fw, square->fh,
0, 0, texture_width, texture_height,
texture_width, texture_height,
- 0, image_format == IMGFMT_YV12, 0);
+ 0, is_yuv, 0);
square++;
} /* for all texnumx */
} /* for all texnumy */
- if (image_format == IMGFMT_YV12)
+ if (is_yuv)
glDisableYUVConversion(GL_TEXTURE_2D, use_yuv);
texdirty = 0;
}
@@ -555,10 +558,11 @@ static int initGl(uint32_t d_width, uint32_t d_height)
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
glEnable (GL_TEXTURE_2D);
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
+ int xs, ys;
gl_conversion_params_t params = {GL_TEXTURE_2D, use_yuv,
- 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
- texture_width, texture_height};
+ {MP_CSP_DEFAULT, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0},
+ texture_width, texture_height, 0, 0, 0};
switch (use_yuv) {
case YUV_CONVERSION_FRAGMENT_LOOKUP:
glGenTextures(1, &lookupTex);
@@ -576,6 +580,9 @@ static int initGl(uint32_t d_width, uint32_t d_height)
BindProgram(GL_FRAGMENT_PROGRAM, fragprog);
break;
}
+ mp_get_chroma_shift(image_format, &xs, &ys);
+ params.chrom_texw = params.texw >> xs;
+ params.chrom_texh = params.texh >> ys;
glSetupYUVConversion(&params);
}
@@ -603,11 +610,14 @@ static int initGl(uint32_t d_width, uint32_t d_height)
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)
{
+ int xs, ys;
const unsigned char * glVersion;
image_height = height;
image_width = width;
image_format = format;
+ is_yuv = mp_get_chroma_shift(image_format, &xs, &ys) > 0;
+ is_yuv |= (xs << 8) | (ys << 16);
#ifdef CONFIG_GL_WIN32
if (config_w32(width, height, d_width, d_height, flags, title, format) == -1)
@@ -729,6 +739,8 @@ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
int rem_h = h;
struct TexSquare *texline = &texgrid[y / texture_height * texnumx];
int subtex_y = y % texture_width;
+ int xs, ys;
+ mp_get_chroma_shift(image_format, &xs, &ys);
while (rem_h > 0) {
int rem_w = w;
struct TexSquare *tsq = &texline[x / texture_width];
@@ -748,24 +760,24 @@ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
ActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[0]);
glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type,
- uptr, ustride, subtex_x / 2, subtex_y / 2,
- subtex_w / 2, subtex_h / 2, 0);
+ uptr, ustride, subtex_x >> xs, subtex_y >> ys,
+ subtex_w >> xs, subtex_h >> ys, 0);
ActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[1]);
glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type,
- vptr, vstride, subtex_x / 2, subtex_y / 2,
- subtex_w / 2, subtex_h / 2, 0);
+ vptr, vstride, subtex_x >> xs, subtex_y >> ys,
+ subtex_w >> xs, subtex_h >> ys, 0);
subtex_x = 0;
yptr += subtex_w;
- uptr += subtex_w / 2;
- vptr += subtex_w / 2;
+ uptr += subtex_w >> xs;
+ vptr += subtex_w >> xs;
tsq++;
rem_w -= subtex_w;
}
subtex_y = 0;
yptr += subtex_h * ystride - w;
- uptr += subtex_h / 2 * ustride - w / 2;
- vptr += subtex_h / 2 * vstride - w / 2;
+ uptr += (subtex_h >> ys) * ustride - (w >> xs);
+ vptr += (subtex_h >> ys) * vstride - (w >> xs);
texline += texnumx;
rem_h -= subtex_h;
}
@@ -776,7 +788,7 @@ static int draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y)
static int
draw_frame(uint8_t *src[])
{
- if (image_format == IMGFMT_YV12) {
+ if (is_yuv) {
mp_msg(MSGT_VO, MSGL_ERR, "[gl2] error: draw_frame called for YV12!\n");
return 0;
}
@@ -789,12 +801,11 @@ draw_frame(uint8_t *src[])
static int
query_format(uint32_t format)
{
+ if (use_yuv && mp_get_chroma_shift(format, NULL, NULL) &&
+ (IMGFMT_IS_YUVP16_NE(format) || !IMGFMT_IS_YUVP16(format)))
+ return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
+ VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;
switch(format) {
- case IMGFMT_YV12:
- if (use_yuv)
- return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
- VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;
- break;
#ifdef __APPLE__
case IMGFMT_RGB32:
#else
@@ -821,7 +832,7 @@ uninit(void)
}
static const opt_t subopts[] = {
- {"yuv", OPT_ARG_INT, &use_yuv, (opt_test_f)int_non_neg},
+ {"yuv", OPT_ARG_INT, &use_yuv, int_non_neg},
{"glfinish", OPT_ARG_BOOL, &use_glFinish, NULL},
{NULL}
};
diff --git a/libvo/vo_ivtv.c b/libvo/vo_ivtv.c
index b80ed44dd9..d39edcbcea 100644
--- a/libvo/vo_ivtv.c
+++ b/libvo/vo_ivtv.c
@@ -60,7 +60,7 @@ static int output = -1;
static char *device = NULL;
static const opt_t subopts[] = {
- {"output", OPT_ARG_INT, &output, (opt_test_f)int_non_neg},
+ {"output", OPT_ARG_INT, &output, int_non_neg},
{"device", OPT_ARG_MSTRZ, &device, NULL},
{NULL}
};
diff --git a/libvo/vo_jpeg.c b/libvo/vo_jpeg.c
index b6a5a8c352..112ec0c2ef 100644
--- a/libvo/vo_jpeg.c
+++ b/libvo/vo_jpeg.c
@@ -330,11 +330,10 @@ static void check_events(void)
/** \brief Validation function for values [0-100]
*/
-static int int_zero_hundred(int *val)
+static int int_zero_hundred(void *valp)
{
- if ( (*val >=0) && (*val<=100) )
- return 1;
- return 0;
+ int *val = valp;
+ return *val >= 0 && *val <= 100;
}
static int preinit(const char *arg)
@@ -343,15 +342,15 @@ static int preinit(const char *arg)
{"progressive", OPT_ARG_BOOL, &jpeg_progressive_mode, NULL},
{"baseline", OPT_ARG_BOOL, &jpeg_baseline, NULL},
{"optimize", OPT_ARG_INT, &jpeg_optimize,
- (opt_test_f)int_zero_hundred},
+ int_zero_hundred},
{"smooth", OPT_ARG_INT, &jpeg_smooth,
- (opt_test_f)int_zero_hundred},
+ int_zero_hundred},
{"quality", OPT_ARG_INT, &jpeg_quality,
- (opt_test_f)int_zero_hundred},
+ int_zero_hundred},
{"dpi", OPT_ARG_INT, &jpeg_dpi, NULL},
{"outdir", OPT_ARG_MSTRZ, &jpeg_outdir, NULL},
{"subdirs", OPT_ARG_MSTRZ, &jpeg_subdirs, NULL},
- {"maxfiles", OPT_ARG_INT, &jpeg_maxfiles, (opt_test_f)int_pos},
+ {"maxfiles", OPT_ARG_INT, &jpeg_maxfiles, int_pos},
{NULL, 0, NULL, NULL}
};
const char *info_message = NULL;
diff --git a/libvo/vo_png.c b/libvo/vo_png.c
index 3d7d33927a..d562a44c46 100644
--- a/libvo/vo_png.c
+++ b/libvo/vo_png.c
@@ -222,16 +222,15 @@ static void uninit(void){}
static void check_events(void){}
-static int int_zero_to_nine(int *sh)
+static int int_zero_to_nine(void *value)
{
- if ( (*sh < 0) || (*sh > 9) )
- return 0;
- return 1;
+ int *sh = value;
+ return *sh >= 0 && *sh <= 9;
}
static const opt_t subopts[] = {
{"alpha", OPT_ARG_BOOL, &use_alpha, NULL},
- {"z", OPT_ARG_INT, &z_compression, (opt_test_f)int_zero_to_nine},
+ {"z", OPT_ARG_INT, &z_compression, int_zero_to_nine},
{NULL}
};
diff --git a/libvo/vo_pnm.c b/libvo/vo_pnm.c
index f8e0b2271b..0ced629da0 100644
--- a/libvo/vo_pnm.c
+++ b/libvo/vo_pnm.c
@@ -128,7 +128,7 @@ static int preinit(const char *arg)
{"ascii", OPT_ARG_BOOL, &ascii_mode, NULL},
{"outdir", OPT_ARG_MSTRZ, &pnm_outdir, NULL},
{"subdirs", OPT_ARG_MSTRZ, &pnm_subdirs, NULL},
- {"maxfiles", OPT_ARG_INT, &pnm_maxfiles, (opt_test_f)int_pos},
+ {"maxfiles", OPT_ARG_INT, &pnm_maxfiles, int_pos},
{NULL, 0, NULL, NULL}
};
const char *info_message = NULL;
diff --git a/libvo/vo_v4l2.c b/libvo/vo_v4l2.c
index c0362aa83c..bb21096b8d 100644
--- a/libvo/vo_v4l2.c
+++ b/libvo/vo_v4l2.c
@@ -54,7 +54,7 @@ static int output = -1;
static char *device = NULL;
static const opt_t subopts[] = {
- {"output", OPT_ARG_INT, &output, (opt_test_f)int_non_neg},
+ {"output", OPT_ARG_INT, &output, int_non_neg},
{"device", OPT_ARG_MSTRZ, &device, NULL},
{NULL}
};
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 7ab087c039..26e03a8941 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -663,13 +663,14 @@ static int preinit(struct vo *vo, const char *arg)
struct vo_x11_state *x11 = vo->x11;
int xv_adaptor = -1;
- const opt_t subopts[] = {
- /* name arg type arg var test */
- {"port", OPT_ARG_INT, &x11->xv_port, (opt_test_f) int_pos},
- {"adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f) int_non_neg},
- {"ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck},
- {"ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm},
- {NULL}
+ const opt_t subopts[] =
+ {
+ /* name arg type arg var test */
+ { "port", OPT_ARG_INT, &x11->xv_port, int_pos },
+ { "adaptor", OPT_ARG_INT, &xv_adaptor, int_non_neg },
+ { "ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck },
+ { "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm },
+ { NULL }
};
x11->xv_port = 0;
diff --git a/libvo/vo_xvmc.c b/libvo/vo_xvmc.c
index 968b11aa0d..ac832d91d3 100644
--- a/libvo/vo_xvmc.c
+++ b/libvo/vo_xvmc.c
@@ -381,8 +381,8 @@ static int preinit(const char *arg){
const opt_t subopts [] =
{
/* name arg type arg var test */
- { "port", OPT_ARG_INT, &xv_port_request, (opt_test_f)int_pos },
- { "adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f)int_non_neg },
+ { "port", OPT_ARG_INT, &xv_port_request, int_pos },
+ { "adaptor", OPT_ARG_INT, &xv_adaptor, int_non_neg },
{ "ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck },
{ "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm },
{ "benchmark", OPT_ARG_BOOL, &benchmark, NULL },
diff --git a/libvo/vo_zr2.c b/libvo/vo_zr2.c
index 2bad93a731..57addb03f1 100644
--- a/libvo/vo_zr2.c
+++ b/libvo/vo_zr2.c
@@ -192,14 +192,16 @@ static int get_norm(const char *n) {
return -1; /* invalid */
}
-static int nc(const char **norm) {
+static int nc(void *normp) {
+ const char **norm = normp;
if (get_norm(*norm) == -1) {
ERROR("norm \"%s\" is not supported, choose from PAL, NTSC, SECAM and auto\n", *norm);
return 0;
} else return 1;
}
-static int pbc(int *prebuf) {
+static int pbc(void *prebufp) {
+ int *prebuf = prebufp;
if (*prebuf) WARNING("prebuffering is not yet supported\n");
return 1;
}
@@ -211,8 +213,8 @@ static int preinit(const char *arg) {
int norm = VIDEO_MODE_AUTO, prebuf = 0;
const opt_t subopts[] = { /* don't want warnings with -Wall... */
{ "dev", OPT_ARG_MSTRZ, &dev_arg, NULL },
- { "prebuf", OPT_ARG_BOOL, &prebuf, (opt_test_f)pbc },
- { "norm", OPT_ARG_MSTRZ, &norm_arg, (opt_test_f)nc },
+ { "prebuf", OPT_ARG_BOOL, &prebuf, pbc },
+ { "norm", OPT_ARG_MSTRZ, &norm_arg, nc },
{ NULL, 0, NULL, NULL }
};
diff --git a/m_option.c b/m_option.c
index 2b10a4f56b..e1c605e4b4 100644
--- a/m_option.c
+++ b/m_option.c
@@ -1024,9 +1024,20 @@ static struct {
const char* name;
unsigned int fmt;
} mp_imgfmt_list[] = {
+ {"444p16le", IMGFMT_444P16_LE},
+ {"444p16be", IMGFMT_444P16_BE},
+ {"422p16le", IMGFMT_422P16_LE},
+ {"422p16be", IMGFMT_422P16_BE},
+ {"420p16le", IMGFMT_420P16_LE},
+ {"420p16be", IMGFMT_420P16_BE},
+ {"444p16", IMGFMT_444P16},
+ {"422p16", IMGFMT_422P16},
+ {"420p16", IMGFMT_420P16},
+ {"420a", IMGFMT_420A},
{"444p", IMGFMT_444P},
{"422p", IMGFMT_422P},
{"411p", IMGFMT_411P},
+ {"440p", IMGFMT_440P},
{"yuy2", IMGFMT_YUY2},
{"uyvy", IMGFMT_UYVY},
{"yvu9", IMGFMT_YVU9},
diff --git a/stream/http.c b/stream/http.c
index 3ebfe03d05..117c531e4c 100644
--- a/stream/http.c
+++ b/stream/http.c
@@ -767,9 +767,12 @@ static int http_streaming_start(stream_t *stream, int* file_format) {
// Check if we can make partial content requests and thus seek in http-streams
if( http_hdr!=NULL && http_hdr->status_code==200 ) {
- char *accept_ranges;
- if( (accept_ranges = http_get_field(http_hdr,"Accept-Ranges")) != NULL )
+ const char *accept_ranges = http_get_field(http_hdr,"Accept-Ranges");
+ const char *server = http_get_field(http_hdr, "Server");
+ if (accept_ranges)
seekable = strncmp(accept_ranges,"bytes",5)==0;
+ else if (server && strcmp(server, "gvs 1.0") == 0)
+ seekable = 1; // HACK for youtube incorrectly claiming not to support seeking
}
print_icy_metadata(http_hdr);
diff --git a/subopt-helper.c b/subopt-helper.c
index ad133772af..fa96ea5052 100644
--- a/subopt-helper.c
+++ b/subopt-helper.c
@@ -300,18 +300,16 @@ static char const * parse_str( char const * str, strarg_t * const valp )
/*** common test functions ***/
/** \brief Test if i is not negative */
-int int_non_neg( int * i )
+int int_non_neg(void *iptr)
{
- if ( *i < 0 ) { return 0; }
-
- return 1;
+ int *i = iptr;
+ return *i >= 0;
}
/** \brief Test if i is positive. */
-int int_pos( int * i )
+int int_pos(void *iptr)
{
- if ( *i > 0 ) { return 1; }
-
- return 0;
+ int *i = iptr;
+ return *i > 0;
}
/*** little helpers */
diff --git a/subopt-helper.h b/subopt-helper.h
index 18c6b4bf86..ec8ff7f378 100644
--- a/subopt-helper.h
+++ b/subopt-helper.h
@@ -38,8 +38,8 @@ typedef struct strarg_s
} strarg_t;
-int int_non_neg( int * i );
-int int_pos( int * i );
+int int_non_neg(void *iptr);
+int int_pos(void *iptr);
int strargcmp(strarg_t *arg, const char *str);
int strargcasecmp(strarg_t *arg, char *str);