mirror of
https://github.com/mpv-player/mpv
synced 2024-07-31 16:29:58 +02:00
Merge svn changes up to r30165
This commit is contained in:
commit
231b33a02f
@ -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
|
||||
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'
|
||||
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
|
||||
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
|
||||
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
|
||||
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'
|
||||
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
|
||||
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
|
||||
.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
|
||||
.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
|
||||
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
|
||||
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
|
||||
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
|
||||
.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
|
||||
.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
|
||||
.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
|
||||
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
|
||||
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
|
||||
|
@ -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 流, 也用来设置最大的传送带宽
|
||||
|
2
Makefile
2
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
|
||||
|
||||
|
11
codec-cfg.c
11
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},
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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},
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -14,37 +14,50 @@
|
||||
|
||||
#include "libvo/fastmemcpy.h"
|
||||
|
||||
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);
|
||||
} else
|
||||
mpi->planes[0]=memalign(64, mpi->bpp*mpi->width*(mpi->height+2)/8);
|
||||
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...
|
||||
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 {
|
||||
// NV12/NV21
|
||||
mpi->stride[1]=mpi->chroma_width;
|
||||
mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
// 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
|
||||
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]) 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 {
|
||||
if(!mpi->stride[0]) mpi->stride[0]=mpi->width*mpi->bpp/8;
|
||||
}
|
||||
mpi->flags|=MP_IMGFLAG_ALLOCATED;
|
||||
mp_image_alloc_planes(mpi);
|
||||
|
||||
return mpi;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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])
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
160
libvo/csputils.c
Normal file
160
libvo/csputils.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
56
libvo/csputils.h
Normal file
56
libvo/csputils.h
Normal file
@ -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 */
|
@ -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(¶ms->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(¶ms->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,
|
||||
@ -1364,29 +1309,6 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) {
|
||||
free(yuv_prog);
|
||||
}
|
||||
|
||||
/**
|
||||
* \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,
|
||||
@ -1394,8 +1316,8 @@ static void gen_gamma_map(unsigned char *map, int size, float gamma) {
|
||||
* \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;
|
||||
|
@ -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;
|
||||
|
||||
|
105
libvo/vo_gl.c
105
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(¶ms);
|
||||
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++)
|
||||
|
@ -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(¶ms);
|
||||
}
|
||||
|
||||
@ -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}
|
||||
};
|
||||
|
@ -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}
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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}
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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 },
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
11
m_option.c
11
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},
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user