From 427039acff27c8d9b605d9b807d6f3a2c15830aa Mon Sep 17 00:00:00 2001 From: gpoirier Date: Tue, 29 Dec 2009 22:16:28 +0000 Subject: [PATCH 01/29] sync w/r30135 (up to date at last!) git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30137 b3059339-0415-0410-9bf9-f77b7e298cf2 --- DOCS/man/fr/mplayer.1 | 133 ++++++++++++++++++++++++++++++------------ 1 file changed, 97 insertions(+), 36 deletions(-) diff --git a/DOCS/man/fr/mplayer.1 b/DOCS/man/fr/mplayer.1 index d43b482a97..9e918d37d9 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 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 (réseau uniquement) +.B \-bandwidth (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= 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= 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 @@ -5374,14 +5432,15 @@ D Défini le niveau d'entrée des basses fréquences (en dixième de dB). .IPs profile= 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 @@ -5466,11 +5525,11 @@ d'entr .PD 0 .RSs .IPs -nombre de canaux de sortie (1\-6) +nombre de canaux de sortie (1\-8) .IPs "\ " -nombre de routes (1\-6) +nombre de routes (1\-8) .IPs -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 @@ -5577,7 +5636,7 @@ Un exemple de mixage de six canaux vers deux .PD 0 .RSs .IPs "\ \ " -nombre de canaux de sortie (1\-6) +nombre de canaux de sortie (1\-8) .IPs 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 @@ -5623,8 +5682,8 @@ aussi bas que possible. Cela améliorera l'effet surround ou stéréo. .IPs "\ " 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'à +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'à si nécessaire. .RE .sp 1 @@ -5648,7 +5707,7 @@ fait une moyenne des canaux et l'att .RSs .IPs 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é à si nécessaire. @@ -5725,8 +5784,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). @@ -7706,6 +7765,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 From 92f20f876f7efac016d9b69aa01fe3d2f0fc6f68 Mon Sep 17 00:00:00 2001 From: reimar Date: Wed, 30 Dec 2009 11:08:44 +0000 Subject: [PATCH 02/29] Add a helper function to get the chroma scale shift and use to simplify mpi setup. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30138 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/img_format.c | 37 +++++++++++++++++++++++++++++++++++++ libmpcodecs/img_format.h | 7 +++++++ libmpcodecs/mp_image.h | 39 ++++++--------------------------------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/libmpcodecs/img_format.c b/libmpcodecs/img_format.c index 2c83a643f7..d4f4d59f38 100644 --- a/libmpcodecs/img_format.c +++ b/libmpcodecs/img_format.c @@ -79,3 +79,40 @@ 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 err = 0; + switch (format) { + 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_444P: + xs = 0; + ys = 0; + break; + case IMGFMT_422P: + xs = 1; + ys = 0; + break; + case IMGFMT_411P: + xs = 2; + ys = 0; + break; + default: + err = 1; + break; + } + if (x_shift) *x_shift = xs; + if (y_shift) *y_shift = ys; + return err ? 0 : 8 + (16 >> (xs + ys)); +} diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h index 4c917b01e4..56d96c481a 100644 --- a/libmpcodecs/img_format.h +++ b/libmpcodecs/img_format.h @@ -133,4 +133,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.h b/libmpcodecs/mp_image.h index 9e02571380..cfc42f81e7 100644 --- a/libmpcodecs/mp_image.h +++ b/libmpcodecs/mp_image.h @@ -133,51 +133,24 @@ 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_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; return; case IMGFMT_Y800: case IMGFMT_Y8: From 8e35068138e7e6398c03b6b38a69be9aaef426c7 Mon Sep 17 00:00:00 2001 From: reimar Date: Wed, 30 Dec 2009 11:32:24 +0000 Subject: [PATCH 03/29] Support all planar YUV formats in OpenGL vos. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30139 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/gl_common.c | 17 ++++++++--- libvo/gl_common.h | 2 ++ libvo/vo_gl.c | 76 +++++++++++++++++++++++++++++------------------ libvo/vo_gl2.c | 60 +++++++++++++++++++++---------------- 4 files changed, 97 insertions(+), 58 deletions(-) diff --git a/libvo/gl_common.c b/libvo/gl_common.c index 47bc727565..9bce6634f0 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -234,6 +234,10 @@ int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt, if (!gl_format) gl_format = &dummy2; if (!gl_type) gl_type = &dummy2; + // these are all the same for our purpose + if (mp_get_chroma_shift(fmt, NULL, NULL)) + fmt = IMGFMT_YV12; + *bpp = IMGFMT_IS_BGR(fmt)?IMGFMT_BGR_DEPTH(fmt):IMGFMT_RGB_DEPTH(fmt); *gl_texfmt = 3; switch (fmt) { @@ -1323,9 +1327,9 @@ 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); + '2', 'b', rect, params->chrom_texw, params->chrom_texh, params->filter_strength); get_yuv2rgb_coeffs(params, yuv2rgb); switch (YUV_CONVERSION(type)) { case YUV_CONVERSION_FRAGMENT: @@ -1496,14 +1500,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 58c4b0dcef..23a78c24a0 100644 --- a/libvo/gl_common.h +++ b/libvo/gl_common.h @@ -339,6 +339,8 @@ typedef struct { float bgamma; 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 5ea2c3c726..058cfb614f 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -93,6 +93,7 @@ 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 is_yuv; static int lscale; static int cscale; static float filter_strength; @@ -206,6 +207,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; @@ -215,7 +217,10 @@ static void update_yuvconv(void) { 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}; + 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"); @@ -478,8 +483,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++) { @@ -490,18 +497,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) { @@ -533,9 +540,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); int_pause = 0; @@ -712,14 +722,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); } @@ -748,13 +758,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; @@ -812,14 +824,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); @@ -869,17 +883,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; @@ -909,7 +925,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); @@ -917,7 +935,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); @@ -925,7 +943,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) { @@ -953,7 +971,7 @@ 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)) 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 @@ -1184,7 +1202,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) { int i; va_list va; int *value; @@ -1200,7 +1218,7 @@ static int control(uint32_t request, void *data, ...) } break; case VOCTRL_SET_EQUALIZER: - if (image_format == IMGFMT_YV12) { + if (is_yuv) { int i; va_list va; int value; diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index 989b470f1a..fc28fe3a67 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -88,6 +88,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) @@ -184,7 +185,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 */ @@ -263,7 +264,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]); @@ -276,13 +277,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); } @@ -381,7 +384,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; @@ -392,7 +395,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); @@ -409,11 +412,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; } @@ -565,10 +568,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}; + texture_width, texture_height, 0, 0, 0}; switch (use_yuv) { case YUV_CONVERSION_FRAGMENT_LOOKUP: glGenTextures(1, &lookupTex); @@ -586,6 +590,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); } @@ -613,11 +620,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); int_pause = 0; @@ -750,6 +760,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]; @@ -769,24 +781,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; } @@ -797,7 +809,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; } @@ -810,12 +822,10 @@ draw_frame(uint8_t *src[]) static int query_format(uint32_t format) { + if (use_yuv && mp_get_chroma_shift(format, NULL, NULL)) + 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 From cc46a64a26bc351a440ac615ac65cec864dba845 Mon Sep 17 00:00:00 2001 From: reimar Date: Wed, 30 Dec 2009 12:03:17 +0000 Subject: [PATCH 04/29] Add support for 440p colorspace. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30140 b3059339-0415-0410-9bf9-f77b7e298cf2 --- codec-cfg.c | 1 + fmt-conversion.c | 2 ++ libmpcodecs/img_format.c | 4 ++++ libmpcodecs/img_format.h | 1 + libmpcodecs/mp_image.h | 1 + m_option.c | 1 + 6 files changed, 10 insertions(+) diff --git a/codec-cfg.c b/codec-cfg.c index b36ecfc50f..8315ef7cf2 100644 --- a/codec-cfg.c +++ b/codec-cfg.c @@ -155,6 +155,7 @@ static int add_to_format(char *s, char *alias,unsigned int *fourcc, unsigned int {"444P", IMGFMT_444P}, {"422P", IMGFMT_422P}, {"411P", IMGFMT_411P}, + {"440P", IMGFMT_440P}, {"Y800", IMGFMT_Y800}, {"Y8", IMGFMT_Y8}, diff --git a/fmt-conversion.c b/fmt-conversion.c index 06699c6ee5..14a1f2df6f 100644 --- a/fmt-conversion.c +++ b/fmt-conversion.c @@ -58,6 +58,7 @@ static const struct { {IMGFMT_411P, PIX_FMT_YUV411P}, {IMGFMT_422P, PIX_FMT_YUV422P}, {IMGFMT_444P, PIX_FMT_YUV444P}, + {IMGFMT_440P, PIX_FMT_YUV440P}, // YUVJ are YUV formats that use the full Y range and not just // 16 - 235 (see colorspaces.txt). @@ -65,6 +66,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/libmpcodecs/img_format.c b/libmpcodecs/img_format.c index d4f4d59f38..bfdcf91b64 100644 --- a/libmpcodecs/img_format.c +++ b/libmpcodecs/img_format.c @@ -108,6 +108,10 @@ int mp_get_chroma_shift(int format, int *x_shift, int *y_shift) xs = 2; ys = 0; break; + case IMGFMT_440P: + xs = 0; + ys = 1; + break; default: err = 1; break; diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h index 56d96c481a..bcbdf0b56e 100644 --- a/libmpcodecs/img_format.h +++ b/libmpcodecs/img_format.h @@ -71,6 +71,7 @@ #define IMGFMT_444P 0x50343434 #define IMGFMT_422P 0x50323234 #define IMGFMT_411P 0x50313134 +#define IMGFMT_440P 0x50303434 #define IMGFMT_HM12 0x32314D48 /* Packed YUV Formats */ diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h index cfc42f81e7..bd750de9ca 100644 --- a/libmpcodecs/mp_image.h +++ b/libmpcodecs/mp_image.h @@ -151,6 +151,7 @@ static inline void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ case IMGFMT_444P: case IMGFMT_422P: case IMGFMT_411P: + case IMGFMT_440P: return; case IMGFMT_Y800: case IMGFMT_Y8: diff --git a/m_option.c b/m_option.c index db45e3c242..752a7f1330 100644 --- a/m_option.c +++ b/m_option.c @@ -1035,6 +1035,7 @@ static struct { {"444p", IMGFMT_444P}, {"422p", IMGFMT_422P}, {"411p", IMGFMT_411P}, + {"440p", IMGFMT_440P}, {"yuy2", IMGFMT_YUY2}, {"uyvy", IMGFMT_UYVY}, {"yvu9", IMGFMT_YVU9}, From 1eb19f0a16850d1552ea368ae905ab8b7f354ab6 Mon Sep 17 00:00:00 2001 From: reimar Date: Wed, 30 Dec 2009 12:03:53 +0000 Subject: [PATCH 05/29] FFmpeg JPEG codecs can output 440p format. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30141 b3059339-0415-0410-9bf9-f77b7e298cf2 --- etc/codecs.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/codecs.conf b/etc/codecs.conf index 5f22c31a2d..89b3e64a08 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 From 22c0b2ed5700946c258b84dd59f584e6a8220468 Mon Sep 17 00:00:00 2001 From: reimar Date: Wed, 30 Dec 2009 12:06:09 +0000 Subject: [PATCH 06/29] Support 440P in scale filter. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30142 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/vf_scale.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c index a18b0ebe7e..000fbacb1b 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -63,6 +63,7 @@ static unsigned int outfmt_list[]={ IMGFMT_NV21, IMGFMT_YUY2, IMGFMT_UYVY, + IMGFMT_440P, // RGB and grayscale (Y8 and Y800): IMGFMT_BGR32, IMGFMT_RGB32, @@ -472,6 +473,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ case IMGFMT_444P: case IMGFMT_422P: case IMGFMT_411P: + case IMGFMT_440P: case IMGFMT_BGR8: case IMGFMT_RGB8: case IMGFMT_BG4B: From 3daa4e73cc243b430447761c6642bfb4f37979aa Mon Sep 17 00:00:00 2001 From: reimar Date: Wed, 30 Dec 2009 19:30:06 +0000 Subject: [PATCH 07/29] Make the ffmpeg decoders for DTS and AC3 the default. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30143 b3059339-0415-0410-9bf9-f77b7e298cf2 --- etc/codecs.conf | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/etc/codecs.conf b/etc/codecs.conf index 89b3e64a08..f4d9793fd1 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -4065,15 +4065,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 @@ -4093,12 +4084,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" @@ -4108,6 +4101,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" From e25e6ec309e08cbf022adbf6027b259fbe5487db Mon Sep 17 00:00:00 2001 From: compn Date: Wed, 30 Dec 2009 19:37:19 +0000 Subject: [PATCH 08/29] add tm2x / tm2a binary decoder git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30144 b3059339-0415-0410-9bf9-f77b7e298cf2 --- etc/codecs.conf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/etc/codecs.conf b/etc/codecs.conf index f4d9793fd1..e4af8b4c2e 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -2239,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 From c97d19eb4978419807cce096a878c4c0cf55b0bb Mon Sep 17 00:00:00 2001 From: reimar Date: Wed, 30 Dec 2009 20:50:03 +0000 Subject: [PATCH 09/29] Add a hack for broken youtube servers not returning Accept-Ranges. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30145 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/http.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stream/http.c b/stream/http.c index 3ebfe03d05..d806632117 100644 --- a/stream/http.c +++ b/stream/http.c @@ -770,6 +770,8 @@ static int http_streaming_start(stream_t *stream, int* file_format) { char *accept_ranges; if( (accept_ranges = http_get_field(http_hdr,"Accept-Ranges")) != NULL ) seekable = strncmp(accept_ranges,"bytes",5)==0; + else if (strcmp(http_get_field(http_hdr, "Server"), "gvs 1.0") == 0) + seekable = 1; // HACK for youtube incorrectly claiming not to support seeking } print_icy_metadata(http_hdr); From 54e6b786f41a9803f4c5c311ec7b310dad2acc16 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 11:29:21 +0000 Subject: [PATCH 10/29] More readable fourcc for ffflac git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30146 b3059339-0415-0410-9bf9-f77b7e298cf2 --- etc/codecs.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/codecs.conf b/etc/codecs.conf index e4af8b4c2e..efa1cafa9e 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -3780,7 +3780,7 @@ audiocodec ffaac audiocodec ffflac info "FFmpeg FLAC audio" status working - format 0x43614C66 + fourcc "fLaC" format 0xF1AC driver ffmpeg dll "flac" From b78313acd8890b2f2181efb92273ae80264a38c1 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 16:46:44 +0000 Subject: [PATCH 11/29] Fix crash if http reply contains neither "Accept-Ranges" nor "Server" fields. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30147 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/http.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stream/http.c b/stream/http.c index d806632117..d81491c6b9 100644 --- a/stream/http.c +++ b/stream/http.c @@ -768,9 +768,10 @@ 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; + const char *server = http_get_field(http_hdr, "Server"); if( (accept_ranges = http_get_field(http_hdr,"Accept-Ranges")) != NULL ) seekable = strncmp(accept_ranges,"bytes",5)==0; - else if (strcmp(http_get_field(http_hdr, "Server"), "gvs 1.0") == 0) + else if (server && strcmp(server, "gvs 1.0") == 0) seekable = 1; // HACK for youtube incorrectly claiming not to support seeking } From 8fb7d45abd13b0d8a427f44f19e338d8b4fb9cc0 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 16:47:53 +0000 Subject: [PATCH 12/29] Make code slightly more readable. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30148 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/http.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stream/http.c b/stream/http.c index d81491c6b9..117c531e4c 100644 --- a/stream/http.c +++ b/stream/http.c @@ -767,9 +767,9 @@ 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; + const char *accept_ranges = http_get_field(http_hdr,"Accept-Ranges"); const char *server = http_get_field(http_hdr, "Server"); - if( (accept_ranges = http_get_field(http_hdr,"Accept-Ranges")) != NULL ) + 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 From c4c806a9d743ec917450515db15b270981930259 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 18:07:37 +0000 Subject: [PATCH 13/29] Put the colourspace-related variables into a separate struct to ease extracting the code and sharing with other vos. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30149 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/gl_common.c | 20 ++++++++++---------- libvo/gl_common.h | 11 ++++++++--- libvo/vo_gl.c | 2 +- libvo/vo_gl2.c | 2 +- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/libvo/gl_common.c b/libvo/gl_common.c index 9bce6634f0..0b63cc6390 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -1018,7 +1018,7 @@ static void gen_gamma_map(unsigned char *map, int size, float gamma); #define COL_V 2 #define COL_C 3 -static void get_yuv2rgb_coeffs(gl_conversion_params_t *params, float yuv2rgb[3][4]) { +static void 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 i; @@ -1049,7 +1049,7 @@ static void get_yuv2rgb_coeffs(gl_conversion_params_t *params, float yuv2rgb[3][ * \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) { +static void 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; @@ -1101,9 +1101,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); + gen_gamma_map(lookup_data, LOOKUP_RES, params->csp_params.rgamma); + gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, params->csp_params.ggamma); + 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, @@ -1121,7 +1121,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); + 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, @@ -1330,7 +1330,7 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) { '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, params->chrom_texw, params->chrom_texh, params->filter_strength); - get_yuv2rgb_coeffs(params, yuv2rgb); + get_yuv2rgb_coeffs(¶ms->csp_params, yuv2rgb); switch (YUV_CONVERSION(type)) { case YUV_CONVERSION_FRAGMENT: snprintf(prog_pos, prog_remain, yuv_prog_template, @@ -1345,7 +1345,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, @@ -1397,8 +1397,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); diff --git a/libvo/gl_common.h b/libvo/gl_common.h index 23a78c24a0..8410c4c954 100644 --- a/libvo/gl_common.h +++ b/libvo/gl_common.h @@ -327,9 +327,8 @@ 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; + +struct mp_csp_params { float brightness; float contrast; float hue; @@ -337,6 +336,12 @@ typedef struct { float rgamma; float ggamma; float bgamma; +}; + +typedef struct { + GLenum target; + int type; + struct mp_csp_params csp_params; int texw; int texh; int chrom_texw; diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 058cfb614f..53ddbad977 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -216,7 +216,7 @@ 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, + {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; diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index fc28fe3a67..bbf850b827 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -571,7 +571,7 @@ static int initGl(uint32_t d_width, uint32_t d_height) 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, + {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: From 0ecf324ac56d58230bcd34faecd92d8749f090a6 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 18:25:35 +0000 Subject: [PATCH 14/29] Extract functions to generate yuv->rgb matrices and lookup tables into a separate file. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30150 b3059339-0415-0410-9bf9-f77b7e298cf2 --- Makefile | 2 +- libvo/csputils.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++ libvo/csputils.h | 45 ++++++++++++++++++ libvo/gl_common.c | 107 +++--------------------------------------- libvo/gl_common.h | 11 +---- 5 files changed, 169 insertions(+), 112 deletions(-) create mode 100644 libvo/csputils.c create mode 100644 libvo/csputils.h diff --git a/Makefile b/Makefile index d0c780c7d9..33db0b7ab1 100644 --- a/Makefile +++ b/Makefile @@ -543,7 +543,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 SRCS_MPLAYER-$(GUI) += gui/bitmap.c diff --git a/libvo/csputils.c b/libvo/csputils.c new file mode 100644 index 0000000000..55ef66d7d4 --- /dev/null +++ b/libvo/csputils.c @@ -0,0 +1,116 @@ +/* + * Common code related to colorspaces and conversion + * + * Copyleft (C) 2009 Reimar Döffinger + * + * 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 +#include +#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 + */ +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 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 + */ +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..1218b1a473 --- /dev/null +++ b/libvo/csputils.h @@ -0,0 +1,45 @@ +/* + * 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 + +struct mp_csp_params { + 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 0b63cc6390..2571959640 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -33,7 +33,7 @@ #include #include #include "gl_common.h" -#include "libavutil/common.h" +#include "csputils.h" void (GLAPIENTRY *Begin)(GLenum); void (GLAPIENTRY *End)(void); @@ -1008,78 +1008,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(struct mp_csp_params *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(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]; - 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 @@ -1101,9 +1029,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->csp_params.rgamma); - gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, params->csp_params.ggamma); - gen_gamma_map(&lookup_data[2 * LOOKUP_RES], LOOKUP_RES, params->csp_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, @@ -1121,7 +1049,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(¶ms->csp_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, @@ -1330,7 +1258,7 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) { '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, params->chrom_texw, params->chrom_texh, params->filter_strength); - get_yuv2rgb_coeffs(¶ms->csp_params, yuv2rgb); + mp_get_yuv2rgb_coeffs(¶ms->csp_params, yuv2rgb); switch (YUV_CONVERSION(type)) { case YUV_CONVERSION_FRAGMENT: snprintf(prog_pos, prog_remain, yuv_prog_template, @@ -1367,29 +1295,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, diff --git a/libvo/gl_common.h b/libvo/gl_common.h index 8410c4c954..db3bb4d8bc 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 @@ -328,16 +329,6 @@ int loadGPUProgram(GLenum target, char *prog); #define YUV_CHROM_SCALER(t) ((t >> YUV_CHROM_SCALER_SHIFT) & YUV_SCALER_MASK) /** \} */ -struct mp_csp_params { - float brightness; - float contrast; - float hue; - float saturation; - float rgamma; - float ggamma; - float bgamma; -}; - typedef struct { GLenum target; int type; From 498ad7ba573b80ac8740886b46f9f8e660647858 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 19:59:58 +0000 Subject: [PATCH 15/29] First steps to supporting different YUV->RGB conversion definitions. The numbers are possibly still wrong though. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30151 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/csputils.c | 46 ++++++++++++++++++++++++++++++++++++++-------- libvo/csputils.h | 10 ++++++++++ libvo/vo_gl.c | 2 +- libvo/vo_gl2.c | 2 +- 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/libvo/csputils.c b/libvo/csputils.c index 55ef66d7d4..b31d9416a8 100644 --- a/libvo/csputils.c +++ b/libvo/csputils.c @@ -56,20 +56,50 @@ void mp_gen_gamma_map(uint8_t *map, int size, float gamma) { 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; - float uv_coeffs[3][2] = { - { 0.000, 1.596}, - {-0.391, -0.813}, - { 2.018, 0.000} + const float (*uv_coeffs)[2]; + static const float level_adjust[4] = {-16 / 255.0, -128 / 255.0, -128 / 255.0, 1.164}; + static const float uv_coeffs_table[MP_CSP_COUNT][3][2] = { + [MP_CSP_DEFAULT] = { + { 0.000, 1.596}, + {-0.391, -0.813}, + { 2.018, 0.000} + }, + [MP_CSP_BT_601] = { + { 0.000, 1.403}, + {-0.344, -0.714}, + { 1.773, 0.000} + }, + [MP_CSP_BT_709] = { + { 0.0000, 1.5701}, + {-0.1870, -0.4664}, + { 1.8556, 0.0000} + }, + [MP_CSP_SMPTE_240M] = { + { 0.0000, 1.5756}, + {-0.2253, -0.5000}, + { 1.8270, 0.0000} + }, + [MP_CSP_EBU] = { + { 0.000, 1.140}, + {-0.396, -0.581}, + { 2.029, 0.000} + }, }; + + if (format < 0 || format >= MP_CSP_COUNT) + format = MP_CSP_DEFAULT; + uv_coeffs = uv_coeffs_table[format]; + 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_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][0] * uvcos + uv_coeffs[i][1] * uvsin; - yuv2rgb[i][COL_C] += (-128 / 255.0) * yuv2rgb[i][COL_U]; + yuv2rgb[i][COL_C] += level_adjust[COL_U] * 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]; + 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; diff --git a/libvo/csputils.h b/libvo/csputils.h index 1218b1a473..29760fd872 100644 --- a/libvo/csputils.h +++ b/libvo/csputils.h @@ -21,7 +21,17 @@ #include +enum mp_csp_standard { + MP_CSP_DEFAULT, + MP_CSP_BT_601, + MP_CSP_BT_709, + MP_CSP_SMPTE_240M, + MP_CSP_EBU, + MP_CSP_COUNT +}; + struct mp_csp_params { + enum mp_csp_standard format; float brightness; float contrast; float hue; diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 53ddbad977..eb71149bbb 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -216,7 +216,7 @@ 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}, + {MP_CSP_DEFAULT, 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; diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index bbf850b827..1cdf7bf83f 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -571,7 +571,7 @@ static int initGl(uint32_t d_width, uint32_t d_height) 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}, + {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: From a326622304cedacce34b31f47dafe7069e076e01 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 22:53:25 +0000 Subject: [PATCH 16/29] Add support for 16-bit per component YUV formats. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30152 b3059339-0415-0410-9bf9-f77b7e298cf2 --- codec-cfg.c | 9 +++++++++ fmt-conversion.c | 6 ++++++ libmpcodecs/img_format.c | 21 ++++++++++++++++++++- libmpcodecs/img_format.h | 20 ++++++++++++++++++++ libmpcodecs/mp_image.c | 13 +++++++------ libmpcodecs/mp_image.h | 6 ++++++ libmpcodecs/vf.c | 15 ++++++++------- libmpcodecs/vf_scale.c | 12 ++++++++++++ libvo/gl_common.c | 19 ++++++++++++++++--- libvo/vo_gl.c | 3 ++- libvo/vo_gl2.c | 3 ++- m_option.c | 9 +++++++++ 12 files changed, 117 insertions(+), 19 deletions(-) diff --git a/codec-cfg.c b/codec-cfg.c index 8315ef7cf2..a0be5df810 100644 --- a/codec-cfg.c +++ b/codec-cfg.c @@ -152,6 +152,15 @@ 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}, {"444P", IMGFMT_444P}, {"422P", IMGFMT_422P}, {"411P", IMGFMT_411P}, diff --git a/fmt-conversion.c b/fmt-conversion.c index 14a1f2df6f..8455277164 100644 --- a/fmt-conversion.c +++ b/fmt-conversion.c @@ -59,6 +59,12 @@ static const struct { {IMGFMT_422P, PIX_FMT_YUV422P}, {IMGFMT_444P, PIX_FMT_YUV444P}, {IMGFMT_440P, PIX_FMT_YUV440P}, + {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). diff --git a/libmpcodecs/img_format.c b/libmpcodecs/img_format.c index bfdcf91b64..d29f47fb1c 100644 --- a/libmpcodecs/img_format.c +++ b/libmpcodecs/img_format.c @@ -37,6 +37,12 @@ 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_444P: return "Planar 444P"; case IMGFMT_422P: return "Planar 422P"; case IMGFMT_411P: return "Planar 411P"; @@ -83,8 +89,13 @@ const char *vo_format_name(int 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_I420: case IMGFMT_IYUV: case IMGFMT_YV12: @@ -96,10 +107,16 @@ int mp_get_chroma_shift(int format, int *x_shift, int *y_shift) 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; @@ -118,5 +135,7 @@ int mp_get_chroma_shift(int format, int *x_shift, int *y_shift) } if (x_shift) *x_shift = xs; if (y_shift) *y_shift = ys; - return err ? 0 : 8 + (16 >> (xs + ys)); + bpp = 8 + (16 >> (xs + ys)); + bpp *= bpp_factor; + return err ? 0 : bpp; } diff --git a/libmpcodecs/img_format.h b/libmpcodecs/img_format.h index bcbdf0b56e..5d3a48caaf 100644 --- a/libmpcodecs/img_format.h +++ b/libmpcodecs/img_format.h @@ -73,6 +73,26 @@ #define IMGFMT_411P 0x50313134 #define IMGFMT_440P 0x50303434 #define IMGFMT_HM12 0x32314D48 +#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 */ diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c index 3eb524d491..3d73a2e3ed 100644 --- a/libmpcodecs/mp_image.c +++ b/libmpcodecs/mp_image.c @@ -29,17 +29,18 @@ mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) { 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(fmt)? 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->stride[0]) mpi->stride[0]=bpp*mpi->width; + if(!mpi->stride[1]) 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->width*mpi->height; - mpi->planes[2]=mpi->planes[1]+mpi->chroma_width*mpi->chroma_height; + mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[2]=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; + mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height; } } else { if(!mpi->stride[0]) mpi->stride[0]=mpi->width*mpi->bpp/8; diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h index bd750de9ca..c4773ce0da 100644 --- a/libmpcodecs/mp_image.h +++ b/libmpcodecs/mp_image.h @@ -152,6 +152,12 @@ static inline void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ case IMGFMT_422P: case IMGFMT_411P: 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: diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c index c2d50b870d..9a03634741 100644 --- a/libmpcodecs/vf.c +++ b/libmpcodecs/vf.c @@ -383,25 +383,26 @@ mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, 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... //if(!mpi->stride[0]) - mpi->stride[0]=mpi->width; + mpi->stride[0]=bpp*mpi->width; //if(!mpi->stride[1]) if(mpi->num_planes > 2){ - mpi->stride[1]=mpi->stride[2]=mpi->chroma_width; + 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->width*mpi->height; - mpi->planes[2]=mpi->planes[1]+mpi->chroma_width*mpi->chroma_height; + mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[2]=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; + mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height; + mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height; } } else { // NV12/NV21 mpi->stride[1]=mpi->chroma_width; - mpi->planes[1]=mpi->planes[0]+mpi->width*mpi->height; + mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; } } else { //if(!mpi->stride[0]) diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c index 000fbacb1b..d2917bffbd 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -64,6 +64,12 @@ static unsigned int outfmt_list[]={ IMGFMT_YUY2, IMGFMT_UYVY, IMGFMT_440P, + IMGFMT_444P16_LE, + IMGFMT_444P16_BE, + IMGFMT_422P16_LE, + IMGFMT_422P16_BE, + IMGFMT_420P16_LE, + IMGFMT_420P16_BE, // RGB and grayscale (Y8 and Y800): IMGFMT_BGR32, IMGFMT_RGB32, @@ -474,6 +480,12 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ case IMGFMT_422P: case IMGFMT_411P: 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: case IMGFMT_BGR8: case IMGFMT_RGB8: case IMGFMT_BG4B: diff --git a/libvo/gl_common.c b/libvo/gl_common.c index 2571959640..ffca3ac35f 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -234,9 +234,15 @@ int glFindFormat(uint32_t fmt, int *bpp, GLint *gl_texfmt, if (!gl_format) gl_format = &dummy2; if (!gl_type) gl_type = &dummy2; - // these are all the same for our purpose - if (mp_get_chroma_shift(fmt, NULL, NULL)) - fmt = IMGFMT_YV12; + 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; @@ -254,6 +260,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: diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index eb71149bbb..95a1b74167 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -971,7 +971,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 && mp_get_chroma_shift(format, NULL, NULL)) + 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 diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index 1cdf7bf83f..626da44c2a 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -822,7 +822,8 @@ draw_frame(uint8_t *src[]) static int query_format(uint32_t format) { - if (use_yuv && mp_get_chroma_shift(format, NULL, NULL)) + 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) { diff --git a/m_option.c b/m_option.c index 752a7f1330..fbde88736b 100644 --- a/m_option.c +++ b/m_option.c @@ -1032,6 +1032,15 @@ 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}, {"444p", IMGFMT_444P}, {"422p", IMGFMT_422P}, {"411p", IMGFMT_411P}, From 2150bddc743b27ad425a3f2388f8b97005ce74ab Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 22:53:51 +0000 Subject: [PATCH 17/29] Add support for FFmpeg's ffv210 codec. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30153 b3059339-0415-0410-9bf9-f77b7e298cf2 --- etc/codecs.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/etc/codecs.conf b/etc/codecs.conf index efa1cafa9e..3d88972068 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -2638,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 From a994808e314ae5d3124e600bf233388c2feea21e Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 23:09:35 +0000 Subject: [PATCH 18/29] Deduplicate the mp_image planes allocation code. The code in vf.c and mp_image.c is almost the same, though the one in vf.c is more up-to-date/has more bug fixes and thus is used as the basis (which is why the diff is so big). git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30154 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/mp_image.c | 66 ++++++++++++++++++++++++------------------ libmpcodecs/vf.c | 40 +------------------------ 2 files changed, 39 insertions(+), 67 deletions(-) diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c index 3d73a2e3ed..02e72bfb24 100644 --- a/libmpcodecs/mp_image.c +++ b/libmpcodecs/mp_image.c @@ -14,38 +14,48 @@ #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); + /* 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) { + int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1; + // YV12/I420/YVU9/IF09. feel free to add other planar formats here... + mpi->stride[0]=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; + } 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; + } + } 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){ - int bpp = IMGFMT_IS_YUVP16(fmt)? 2 : 1; - // YV12/I420/YVU9/IF09. feel free to add other planar formats here... - if(!mpi->stride[0]) mpi->stride[0]=bpp*mpi->width; - if(!mpi->stride[1]) 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; - } 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; - } - } 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; } diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c index 9a03634741..4cace80593 100644 --- a/libmpcodecs/vf.c +++ b/libmpcodecs/vf.c @@ -372,47 +372,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){ - 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]=bpp*mpi->width; - //if(!mpi->stride[1]) - 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; - } 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; - } - } else { - // 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; - 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) From 0ff930da825b29fc0e7c9955c33695dbe784dbb3 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 23:25:21 +0000 Subject: [PATCH 19/29] Try to put the list of output formats for vf_scale in a more sensible order. While the 16-bit yuv formats should not be preferred over the 8-bit ones, it seems reasonable to probe them directly after the equivalent 8-bit formats. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30155 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/vf_scale.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c index d2917bffbd..f2b375a26f 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -52,9 +52,15 @@ void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, Sw static 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_IYUV, IMGFMT_YVU9, IMGFMT_IF09, @@ -64,12 +70,6 @@ static unsigned int outfmt_list[]={ IMGFMT_YUY2, IMGFMT_UYVY, IMGFMT_440P, - IMGFMT_444P16_LE, - IMGFMT_444P16_BE, - IMGFMT_422P16_LE, - IMGFMT_422P16_BE, - IMGFMT_420P16_LE, - IMGFMT_420P16_BE, // RGB and grayscale (Y8 and Y800): IMGFMT_BGR32, IMGFMT_RGB32, From c07dec1a4a6e6e0695f3893c60a42e9a14daefaf Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 23:39:21 +0000 Subject: [PATCH 20/29] Also pass the 4th plane for planar formats on to libavcodec. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30156 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/vd_ffmpeg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c index a3cb9ee1d8..ded6feb4f8 100644 --- a/libmpcodecs/vd_ffmpeg.c +++ b/libmpcodecs/vd_ffmpeg.c @@ -639,6 +639,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))); @@ -663,6 +664,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]); @@ -884,9 +886,11 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){ 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]) From 8afc25d710d8520b454d48b7744dde4812feef74 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 23:45:07 +0000 Subject: [PATCH 21/29] Add support for YUV format with alpha and fix the codecs.conf entry for vp6a to use it. Fixes playback of samples in http://samples.mplayerhq.hu/FLV/flash_with_alpha/ git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30157 b3059339-0415-0410-9bf9-f77b7e298cf2 --- codec-cfg.c | 1 + etc/codecs.conf | 2 +- fmt-conversion.c | 3 +++ libmpcodecs/img_format.c | 4 ++++ libmpcodecs/img_format.h | 4 ++++ libmpcodecs/mp_image.c | 8 +++++--- libmpcodecs/mp_image.h | 2 ++ libmpcodecs/vf_scale.c | 2 ++ m_option.c | 1 + 9 files changed, 23 insertions(+), 4 deletions(-) diff --git a/codec-cfg.c b/codec-cfg.c index a0be5df810..840fb94ec1 100644 --- a/codec-cfg.c +++ b/codec-cfg.c @@ -161,6 +161,7 @@ static int add_to_format(char *s, char *alias,unsigned int *fourcc, unsigned int {"444P16", IMGFMT_444P16}, {"422P16", IMGFMT_422P16}, {"420P16", IMGFMT_420P16}, + {"420A", IMGFMT_420A}, {"444P", IMGFMT_444P}, {"422P", IMGFMT_422P}, {"411P", IMGFMT_411P}, diff --git a/etc/codecs.conf b/etc/codecs.conf index 3d88972068..be548cac61 100644 --- a/etc/codecs.conf +++ b/etc/codecs.conf @@ -2060,7 +2060,7 @@ videocodec ffvp6a fourcc VP6A driver ffmpeg dll "vp6a" - out I420,YUY2,YV12 + out 420A videocodec ffvp6f info "FFmpeg VP6 Flash" diff --git a/fmt-conversion.c b/fmt-conversion.c index 8455277164..9371ab1a11 100644 --- a/fmt-conversion.c +++ b/fmt-conversion.c @@ -59,6 +59,9 @@ static const struct { {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}, diff --git a/libmpcodecs/img_format.c b/libmpcodecs/img_format.c index d29f47fb1c..cc7bee10b8 100644 --- a/libmpcodecs/img_format.c +++ b/libmpcodecs/img_format.c @@ -43,6 +43,7 @@ const char *vo_format_name(int format) 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"; @@ -96,6 +97,7 @@ int mp_get_chroma_shift(int format, int *x_shift, int *y_shift) case IMGFMT_420P16_LE: case IMGFMT_420P16_BE: bpp_factor = 2; + case IMGFMT_420A: case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YV12: @@ -136,6 +138,8 @@ int mp_get_chroma_shift(int format, int *x_shift, int *y_shift) 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 5d3a48caaf..6bab56632d 100644 --- a/libmpcodecs/img_format.h +++ b/libmpcodecs/img_format.h @@ -73,6 +73,10 @@ #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 diff --git a/libmpcodecs/mp_image.c b/libmpcodecs/mp_image.c index 02e72bfb24..1bc0492e9c 100644 --- a/libmpcodecs/mp_image.c +++ b/libmpcodecs/mp_image.c @@ -19,24 +19,26 @@ void mp_image_alloc_planes(mp_image_t *mpi) { 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) { int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1; // YV12/I420/YVU9/IF09. feel free to add other planar formats here... - mpi->stride[0]=bpp*mpi->width; + 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 diff --git a/libmpcodecs/mp_image.h b/libmpcodecs/mp_image.h index c4773ce0da..a53ef8a5ad 100644 --- a/libmpcodecs/mp_image.h +++ b/libmpcodecs/mp_image.h @@ -145,6 +145,7 @@ static inline void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ mpi->flags|=MP_IMGFLAG_SWAPPED; case IMGFMT_YV12: return; + case IMGFMT_420A: case IMGFMT_IF09: mpi->num_planes=4; case IMGFMT_YVU9: @@ -210,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/vf_scale.c b/libmpcodecs/vf_scale.c index f2b375a26f..0131b36d82 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -61,6 +61,7 @@ static unsigned int outfmt_list[]={ IMGFMT_I420, IMGFMT_420P16_LE, IMGFMT_420P16_BE, + IMGFMT_420A, IMGFMT_IYUV, IMGFMT_YVU9, IMGFMT_IF09, @@ -480,6 +481,7 @@ static int query_format(struct vf_instance_s* vf, unsigned int fmt){ case IMGFMT_422P: case IMGFMT_411P: case IMGFMT_440P: + case IMGFMT_420A: case IMGFMT_444P16_LE: case IMGFMT_444P16_BE: case IMGFMT_422P16_LE: diff --git a/m_option.c b/m_option.c index fbde88736b..8c5c42982d 100644 --- a/m_option.c +++ b/m_option.c @@ -1041,6 +1041,7 @@ static struct { {"444p16", IMGFMT_444P16}, {"422p16", IMGFMT_422P16}, {"420p16", IMGFMT_420P16}, + {"420a", IMGFMT_420A}, {"444p", IMGFMT_444P}, {"422p", IMGFMT_422P}, {"411p", IMGFMT_411P}, From c0cae7b3275b81d539f3d11fe64687ed6294ebfe Mon Sep 17 00:00:00 2001 From: reimar Date: Fri, 1 Jan 2010 01:06:34 +0000 Subject: [PATCH 22/29] Also pass alpha plane to swscale, avoids crashes when converting between YUV with alpha and some other format supporting alpha. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30158 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/vf_scale.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c index 0131b36d82..3435f75447 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -331,7 +331,7 @@ static void start_slice(struct vf_instance_s* 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]){ @@ -344,9 +344,9 @@ 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++){ From 0eb6b9aa95c0546313a3d5351378aab45dccca5e Mon Sep 17 00:00:00 2001 From: reimar Date: Fri, 1 Jan 2010 01:25:35 +0000 Subject: [PATCH 23/29] One more fix for -vf scale with alpha. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30159 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/vf_scale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmpcodecs/vf_scale.c b/libmpcodecs/vf_scale.c index 3435f75447..e32d403538 100644 --- a/libmpcodecs/vf_scale.c +++ b/libmpcodecs/vf_scale.c @@ -349,7 +349,7 @@ static void scale(struct SwsContext *sws1, struct SwsContext *sws2, uint8_t *src 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 Date: Fri, 1 Jan 2010 09:46:24 +0000 Subject: [PATCH 24/29] Do not needlessly use the BP register in x86_64-specific code, there are enough other registers available that are less likely to cause issues. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30160 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libswscale/swscale_template.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libswscale/swscale_template.c b/libswscale/swscale_template.c index 5bf66d5ba9..d14cf8f4a4 100644 --- a/libswscale/swscale_template.c +++ b/libswscale/swscale_template.c @@ -1226,17 +1226,17 @@ static inline void RENAME(yuv2packed2)(SwsContext *c, const uint16_t *buf0, cons if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) { #if ARCH_X86_64 __asm__ volatile( - YSCALEYUV2RGB(%%REGBP, %5) - YSCALEYUV2RGB_YA(%%REGBP, %5, %6, %7) + YSCALEYUV2RGB(%%r8, %5) + YSCALEYUV2RGB_YA(%%r8, %5, %6, %7) "psraw $3, %%mm1 \n\t" /* abuf0[eax] - abuf1[eax] >>7*/ "psraw $3, %%mm7 \n\t" /* abuf0[eax] - abuf1[eax] >>7*/ "packuswb %%mm7, %%mm1 \n\t" - WRITEBGR32(%4, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) + WRITEBGR32(%4, 8280(%5), %%r8, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "r" (dest), "a" (&c->redDither) ,"r" (abuf0), "r" (abuf1) - : "%"REG_BP + : "%r8" ); #else *(uint16_t **)(&c->u_temp)=abuf0; From 64502716566cc7a9da4655ddd1fc6b442db47670 Mon Sep 17 00:00:00 2001 From: reimar Date: Fri, 1 Jan 2010 12:47:43 +0000 Subject: [PATCH 25/29] Make YUV->RGB conversion coefficients selectable for -vo gl. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30161 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/vo_gl.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 95a1b74167..3f37c301c7 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -93,6 +93,7 @@ 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; @@ -216,7 +217,7 @@ 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, - {MP_CSP_DEFAULT, bri, cont, hue, sat, rgamma, ggamma, bgamma}, + {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; @@ -999,6 +1000,12 @@ 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}, @@ -1008,6 +1015,7 @@ static const opt_t subopts[] = { {"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}, + {"colorspace", OPT_ARG_INT, &colorspace, valid_csp}, {"lscale", OPT_ARG_INT, &lscale, (opt_test_f)int_non_neg}, {"cscale", OPT_ARG_INT, &cscale, (opt_test_f)int_non_neg}, {"filter-strength", OPT_ARG_FLOAT, &filter_strength, NULL}, @@ -1038,6 +1046,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; @@ -1093,6 +1102,12 @@ 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" + " 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" " lscale=\n" " 0: use standard bilinear scaling for luma.\n" " 1: use improved bicubic scaling for luma.\n" From 85344073fa9d45db689dc2529f1c48c889d84cc1 Mon Sep 17 00:00:00 2001 From: jrash Date: Fri, 1 Jan 2010 12:53:28 +0000 Subject: [PATCH 26/29] sync with en/mplayer.1 r30135 git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30162 b3059339-0415-0410-9bf9-f77b7e298cf2 --- DOCS/man/zh_CN/mplayer.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 æµ, 也用æ¥è®¾ç½®æœ€å¤§çš„ä¼ é€å¸¦å®½ From 5f684e1b32cc052edf33d8c0ff5ead106e98e680 Mon Sep 17 00:00:00 2001 From: reimar Date: Fri, 1 Jan 2010 12:54:09 +0000 Subject: [PATCH 27/29] Slightly generalize code to generate YUV->RGB conversion table and add XYZ->RGB conversion as an example for that. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30163 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libvo/csputils.c | 56 ++++++++++++++++++++++++++++++------------------ libvo/csputils.h | 1 + libvo/vo_gl.c | 1 + 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/libvo/csputils.c b/libvo/csputils.c index b31d9416a8..6f69ec4212 100644 --- a/libvo/csputils.c +++ b/libvo/csputils.c @@ -52,53 +52,67 @@ void mp_gen_gamma_map(uint8_t *map, int size, float gamma) { * \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)[2]; - static const float level_adjust[4] = {-16 / 255.0, -128 / 255.0, -128 / 255.0, 1.164}; - static const float uv_coeffs_table[MP_CSP_COUNT][3][2] = { + 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] = { - { 0.000, 1.596}, - {-0.391, -0.813}, - { 2.018, 0.000} + {1, 0.000, 1.596}, + {1, -0.391, -0.813}, + {1, 2.018, 0.000} }, [MP_CSP_BT_601] = { - { 0.000, 1.403}, - {-0.344, -0.714}, - { 1.773, 0.000} + {1, 0.000, 1.403}, + {1, -0.344, -0.714}, + {1, 1.773, 0.000} }, [MP_CSP_BT_709] = { - { 0.0000, 1.5701}, - {-0.1870, -0.4664}, - { 1.8556, 0.0000} + {1, 0.0000, 1.5701}, + {1, -0.1870, -0.4664}, + {1, 1.8556, 0.0000} }, [MP_CSP_SMPTE_240M] = { - { 0.0000, 1.5756}, - {-0.2253, -0.5000}, - { 1.8270, 0.0000} + {1, 0.0000, 1.5756}, + {1, -0.2253, -0.5000}, + {1, 1.8270, 0.0000} }, [MP_CSP_EBU] = { - { 0.000, 1.140}, - {-0.396, -0.581}, - { 2.029, 0.000} + {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] = level_adjust[COL_C] * params->contrast; + 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][0] * uvcos + uv_coeffs[i][1] * uvsin; + 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][0] * uvsin + uv_coeffs[i][1] * uvcos; + 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 diff --git a/libvo/csputils.h b/libvo/csputils.h index 29760fd872..4723c7006d 100644 --- a/libvo/csputils.h +++ b/libvo/csputils.h @@ -27,6 +27,7 @@ enum mp_csp_standard { MP_CSP_BT_709, MP_CSP_SMPTE_240M, MP_CSP_EBU, + MP_CSP_XYZ, MP_CSP_COUNT }; diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c index 3f37c301c7..51e5b0fb03 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -1108,6 +1108,7 @@ static int preinit(const char *arg) " 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" " 0: use standard bilinear scaling for luma.\n" " 1: use improved bicubic scaling for luma.\n" From f102ac7a8c62491761b7b3d32baa87dcb665f9ed Mon Sep 17 00:00:00 2001 From: reimar Date: Fri, 1 Jan 2010 13:18:49 +0000 Subject: [PATCH 28/29] Fix function declarations to avoid casting function pointers. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30164 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libao2/ao_alsa.c | 5 +++-- libao2/ao_dart.c | 2 +- libvo/vo_gl.c | 10 +++++----- libvo/vo_gl2.c | 2 +- libvo/vo_ivtv.c | 2 +- libvo/vo_jpeg.c | 11 ++++++----- libvo/vo_png.c | 5 +++-- libvo/vo_pnm.c | 2 +- libvo/vo_v4l2.c | 2 +- libvo/vo_xv.c | 4 ++-- libvo/vo_xvmc.c | 4 ++-- libvo/vo_zr2.c | 10 ++++++---- subopt-helper.c | 6 ++++-- subopt-helper.h | 4 ++-- 14 files changed, 38 insertions(+), 31 deletions(-) diff --git a/libao2/ao_alsa.c b/libao2/ao_alsa.c index 7376c0f18d..ba49231b28 100644 --- a/libao2/ao_alsa.c +++ b/libao2/ao_alsa.c @@ -263,7 +263,8 @@ static void print_help (void) MSGTR_AO_ALSA_CommandlineHelp); } -static int str_maxlen(strarg_t *str) { +static int str_maxlen(void *strp) { + strarg_t *str = strp; if (str->len > ALSA_DEVICE_SIZE) return 0; return 1; @@ -328,7 +329,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/libvo/vo_gl.c b/libvo/vo_gl.c index 51e5b0fb03..071fccebb2 100644 --- a/libvo/vo_gl.c +++ b/libvo/vo_gl.c @@ -1012,12 +1012,12 @@ static const opt_t subopts[] = { {"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}, + {"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, (opt_test_f)int_non_neg}, - {"cscale", OPT_ARG_INT, &cscale, (opt_test_f)int_non_neg}, + {"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}, diff --git a/libvo/vo_gl2.c b/libvo/vo_gl2.c index 626da44c2a..b65acf589c 100644 --- a/libvo/vo_gl2.c +++ b/libvo/vo_gl2.c @@ -853,7 +853,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 e62308722a..8c79bf4041 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 72cb2a5b22..5f9a5d1f6d 100644 --- a/libvo/vo_jpeg.c +++ b/libvo/vo_jpeg.c @@ -330,8 +330,9 @@ 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) { + int *val = valp; if ( (*val >=0) && (*val<=100) ) return 1; return 0; @@ -343,15 +344,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 8110f859df..e404785736 100644 --- a/libvo/vo_png.c +++ b/libvo/vo_png.c @@ -283,8 +283,9 @@ 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) { + int *sh = value; if ( (*sh < 0) || (*sh > 9) ) return 0; return 1; @@ -292,7 +293,7 @@ static int int_zero_to_nine(int *sh) 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}, {"outdir", OPT_ARG_MSTRZ, &png_outdir, NULL}, {NULL} }; diff --git a/libvo/vo_pnm.c b/libvo/vo_pnm.c index 90caf55e24..20290272bc 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 62808f8291..f2e6535bab 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 451d575884..6f1f7b6a36 100644 --- a/libvo/vo_xv.c +++ b/libvo/vo_xv.c @@ -612,8 +612,8 @@ static int preinit(const char *arg) const opt_t subopts[] = { /* name arg type arg var test */ - { "port", OPT_ARG_INT, &xv_port, (opt_test_f)int_pos }, - { "adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f)int_non_neg }, + { "port", OPT_ARG_INT, &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 } diff --git a/libvo/vo_xvmc.c b/libvo/vo_xvmc.c index 1673fa8774..76954b2649 100644 --- a/libvo/vo_xvmc.c +++ b/libvo/vo_xvmc.c @@ -382,8 +382,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 21347cb1d7..9f086cc4e1 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/subopt-helper.c b/subopt-helper.c index 50283cfbf3..e40f9f40d0 100644 --- a/subopt-helper.c +++ b/subopt-helper.c @@ -300,15 +300,17 @@ 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) { + int *i = iptr; if ( *i < 0 ) { return 0; } return 1; } /** \brief Test if i is positive. */ -int int_pos( int * i ) +int int_pos(void *iptr) { + int *i = iptr; if ( *i > 0 ) { return 1; } return 0; 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); From 92cd6dc3e916ae4275ff05d2b238fc778cfbfc6b Mon Sep 17 00:00:00 2001 From: reimar Date: Fri, 1 Jan 2010 13:23:16 +0000 Subject: [PATCH 29/29] Simplify range-checking functions for subopt parsing. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30165 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libao2/ao_alsa.c | 4 +--- libvo/vo_jpeg.c | 4 +--- libvo/vo_png.c | 4 +--- subopt-helper.c | 8 ++------ 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/libao2/ao_alsa.c b/libao2/ao_alsa.c index ba49231b28..70cd92198b 100644 --- a/libao2/ao_alsa.c +++ b/libao2/ao_alsa.c @@ -265,9 +265,7 @@ static void print_help (void) static int str_maxlen(void *strp) { strarg_t *str = strp; - if (str->len > ALSA_DEVICE_SIZE) - return 0; - return 1; + return str->len <= ALSA_DEVICE_SIZE; } static int try_open_device(const char *device, int open_mode, int try_ac3) diff --git a/libvo/vo_jpeg.c b/libvo/vo_jpeg.c index 5f9a5d1f6d..1be11014b0 100644 --- a/libvo/vo_jpeg.c +++ b/libvo/vo_jpeg.c @@ -333,9 +333,7 @@ static void check_events(void) static int int_zero_hundred(void *valp) { int *val = valp; - if ( (*val >=0) && (*val<=100) ) - return 1; - return 0; + return *val >= 0 && *val <= 100; } static int preinit(const char *arg) diff --git a/libvo/vo_png.c b/libvo/vo_png.c index e404785736..94fbdcaf8f 100644 --- a/libvo/vo_png.c +++ b/libvo/vo_png.c @@ -286,9 +286,7 @@ static void check_events(void){} static int int_zero_to_nine(void *value) { int *sh = value; - if ( (*sh < 0) || (*sh > 9) ) - return 0; - return 1; + return *sh >= 0 && *sh <= 9; } static const opt_t subopts[] = { diff --git a/subopt-helper.c b/subopt-helper.c index e40f9f40d0..6167778b9f 100644 --- a/subopt-helper.c +++ b/subopt-helper.c @@ -303,17 +303,13 @@ static char const * parse_str( char const * str, strarg_t * const valp ) int int_non_neg(void *iptr) { int *i = iptr; - if ( *i < 0 ) { return 0; } - - return 1; + return *i >= 0; } /** \brief Test if i is positive. */ int int_pos(void *iptr) { int *i = iptr; - if ( *i > 0 ) { return 1; } - - return 0; + return *i > 0; } /*** little helpers */