Mercurial > mplayer.hg
comparison libvo/vo_gl2.c @ 30097:9d724e6def3e
Support all planar YUV formats in OpenGL vos.
author | reimar |
---|---|
date | Wed, 30 Dec 2009 11:32:24 +0000 |
parents | b7a703cf9178 |
children | 11e3ee8cd05e |
comparison
equal
deleted
inserted
replaced
30096:76c25bfa181b | 30097:9d724e6def3e |
---|---|
86 static int isGL12 = GL_FALSE; | 86 static int isGL12 = GL_FALSE; |
87 | 87 |
88 static int gl_bilinear=1; | 88 static int gl_bilinear=1; |
89 static int gl_antialias=0; | 89 static int gl_antialias=0; |
90 static int use_yuv; | 90 static int use_yuv; |
91 static int is_yuv; | |
91 static int use_glFinish; | 92 static int use_glFinish; |
92 | 93 |
93 static void (*draw_alpha_fnc) | 94 static void (*draw_alpha_fnc) |
94 (int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride); | 95 (int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride); |
95 | 96 |
182 s=64; | 183 s=64; |
183 while (s<image_height) | 184 while (s<image_height) |
184 s*=2; | 185 s*=2; |
185 texture_height=s; | 186 texture_height=s; |
186 | 187 |
187 if (image_format != IMGFMT_YV12) | 188 if (!is_yuv) |
188 gl_internal_format = getInternalFormat(); | 189 gl_internal_format = getInternalFormat(); |
189 | 190 |
190 /* Test the max texture size */ | 191 /* Test the max texture size */ |
191 do { | 192 do { |
192 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, | 193 glTexImage2D (GL_PROXY_TEXTURE_2D, 0, |
261 tsq->uvtexobjs[0] = tsq->uvtexobjs[1] = 0; | 262 tsq->uvtexobjs[0] = tsq->uvtexobjs[1] = 0; |
262 | 263 |
263 glGenTextures (1, &(tsq->texobj)); | 264 glGenTextures (1, &(tsq->texobj)); |
264 | 265 |
265 glBindTexture (GL_TEXTURE_2D, tsq->texobj); | 266 glBindTexture (GL_TEXTURE_2D, tsq->texobj); |
266 if (image_format == IMGFMT_YV12) { | 267 if (is_yuv) { |
267 glGenTextures(2, tsq->uvtexobjs); | 268 glGenTextures(2, tsq->uvtexobjs); |
268 ActiveTexture(GL_TEXTURE1); | 269 ActiveTexture(GL_TEXTURE1); |
269 glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[0]); | 270 glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[0]); |
270 ActiveTexture(GL_TEXTURE2); | 271 ActiveTexture(GL_TEXTURE2); |
271 glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[1]); | 272 glBindTexture (GL_TEXTURE_2D, tsq->uvtexobjs[1]); |
274 | 275 |
275 glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR, | 276 glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR, |
276 texture_width, texture_height, 0); | 277 texture_width, texture_height, 0); |
277 | 278 |
278 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | 279 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
279 if (image_format == IMGFMT_YV12) { | 280 if (is_yuv) { |
281 int xs, ys; | |
282 mp_get_chroma_shift(image_format, &xs, &ys); | |
280 ActiveTexture(GL_TEXTURE1); | 283 ActiveTexture(GL_TEXTURE1); |
281 glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR, | 284 glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR, |
282 texture_width / 2, texture_height / 2, 128); | 285 texture_width >> xs, texture_height >> ys, 128); |
283 ActiveTexture(GL_TEXTURE2); | 286 ActiveTexture(GL_TEXTURE2); |
284 glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR, | 287 glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format, gl_bitmap_type, GL_LINEAR, |
285 texture_width / 2, texture_height / 2, 128); | 288 texture_width >> xs, texture_height >> ys, 128); |
286 ActiveTexture(GL_TEXTURE0); | 289 ActiveTexture(GL_TEXTURE0); |
287 } | 290 } |
288 | 291 |
289 tsq++; | 292 tsq++; |
290 } /* for all texnumx */ | 293 } /* for all texnumx */ |
379 struct TexSquare *square = texgrid; | 382 struct TexSquare *square = texgrid; |
380 int x, y; | 383 int x, y; |
381 | 384 |
382 glColor3f(1.0,1.0,1.0); | 385 glColor3f(1.0,1.0,1.0); |
383 | 386 |
384 if (image_format == IMGFMT_YV12) | 387 if (is_yuv) |
385 glEnableYUVConversion(GL_TEXTURE_2D, use_yuv); | 388 glEnableYUVConversion(GL_TEXTURE_2D, use_yuv); |
386 for (y = 0; y < texnumy; y++) { | 389 for (y = 0; y < texnumy; y++) { |
387 int thish = texture_height; | 390 int thish = texture_height; |
388 if (y == texnumy - 1 && image_height % texture_height) | 391 if (y == texnumy - 1 && image_height % texture_height) |
389 thish = image_height % texture_height; | 392 thish = image_height % texture_height; |
390 for (x = 0; x < texnumx; x++) { | 393 for (x = 0; x < texnumx; x++) { |
391 int thisw = texture_width; | 394 int thisw = texture_width; |
392 if (x == texnumx - 1 && image_width % texture_width) | 395 if (x == texnumx - 1 && image_width % texture_width) |
393 thisw = image_width % texture_width; | 396 thisw = image_width % texture_width; |
394 glBindTexture (GL_TEXTURE_2D, square->texobj); | 397 glBindTexture (GL_TEXTURE_2D, square->texobj); |
395 if (image_format == IMGFMT_YV12) { | 398 if (is_yuv) { |
396 ActiveTexture(GL_TEXTURE1); | 399 ActiveTexture(GL_TEXTURE1); |
397 glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[0]); | 400 glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[0]); |
398 ActiveTexture(GL_TEXTURE2); | 401 ActiveTexture(GL_TEXTURE2); |
399 glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[1]); | 402 glBindTexture (GL_TEXTURE_2D, square->uvtexobjs[1]); |
400 ActiveTexture(GL_TEXTURE0); | 403 ActiveTexture(GL_TEXTURE0); |
407 } | 410 } |
408 | 411 |
409 glDrawTex(square->fx, square->fy, square->fw, square->fh, | 412 glDrawTex(square->fx, square->fy, square->fw, square->fh, |
410 0, 0, texture_width, texture_height, | 413 0, 0, texture_width, texture_height, |
411 texture_width, texture_height, | 414 texture_width, texture_height, |
412 0, image_format == IMGFMT_YV12, 0); | 415 0, is_yuv, 0); |
413 square++; | 416 square++; |
414 } /* for all texnumx */ | 417 } /* for all texnumx */ |
415 } /* for all texnumy */ | 418 } /* for all texnumy */ |
416 if (image_format == IMGFMT_YV12) | 419 if (is_yuv) |
417 glDisableYUVConversion(GL_TEXTURE_2D, use_yuv); | 420 glDisableYUVConversion(GL_TEXTURE_2D, use_yuv); |
418 texdirty = 0; | 421 texdirty = 0; |
419 } | 422 } |
420 | 423 |
421 | 424 |
563 glDisable(GL_BLEND); | 566 glDisable(GL_BLEND); |
564 glDisable(GL_DEPTH_TEST); | 567 glDisable(GL_DEPTH_TEST); |
565 glDepthMask(GL_FALSE); | 568 glDepthMask(GL_FALSE); |
566 glDisable(GL_CULL_FACE); | 569 glDisable(GL_CULL_FACE); |
567 glEnable (GL_TEXTURE_2D); | 570 glEnable (GL_TEXTURE_2D); |
568 if (image_format == IMGFMT_YV12) { | 571 if (is_yuv) { |
572 int xs, ys; | |
569 gl_conversion_params_t params = {GL_TEXTURE_2D, use_yuv, | 573 gl_conversion_params_t params = {GL_TEXTURE_2D, use_yuv, |
570 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, | 574 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, |
571 texture_width, texture_height}; | 575 texture_width, texture_height, 0, 0, 0}; |
572 switch (use_yuv) { | 576 switch (use_yuv) { |
573 case YUV_CONVERSION_FRAGMENT_LOOKUP: | 577 case YUV_CONVERSION_FRAGMENT_LOOKUP: |
574 glGenTextures(1, &lookupTex); | 578 glGenTextures(1, &lookupTex); |
575 ActiveTexture(GL_TEXTURE3); | 579 ActiveTexture(GL_TEXTURE3); |
576 glBindTexture(GL_TEXTURE_2D, lookupTex); | 580 glBindTexture(GL_TEXTURE_2D, lookupTex); |
584 } | 588 } |
585 GenPrograms(1, &fragprog); | 589 GenPrograms(1, &fragprog); |
586 BindProgram(GL_FRAGMENT_PROGRAM, fragprog); | 590 BindProgram(GL_FRAGMENT_PROGRAM, fragprog); |
587 break; | 591 break; |
588 } | 592 } |
593 mp_get_chroma_shift(image_format, &xs, &ys); | |
594 params.chrom_texw = params.texw >> xs; | |
595 params.chrom_texh = params.texh >> ys; | |
589 glSetupYUVConversion(¶ms); | 596 glSetupYUVConversion(¶ms); |
590 } | 597 } |
591 | 598 |
592 gl_set_antialias(0); | 599 gl_set_antialias(0); |
593 gl_set_bilinear(1); | 600 gl_set_bilinear(1); |
611 * allocate colors and (shared) memory | 618 * allocate colors and (shared) memory |
612 */ | 619 */ |
613 static int | 620 static int |
614 config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) | 621 config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format) |
615 { | 622 { |
623 int xs, ys; | |
616 const unsigned char * glVersion; | 624 const unsigned char * glVersion; |
617 | 625 |
618 image_height = height; | 626 image_height = height; |
619 image_width = width; | 627 image_width = width; |
620 image_format = format; | 628 image_format = format; |
629 is_yuv = mp_get_chroma_shift(image_format, &xs, &ys) > 0; | |
630 is_yuv |= (xs << 8) | (ys << 16); | |
621 | 631 |
622 int_pause = 0; | 632 int_pause = 0; |
623 | 633 |
624 #ifdef CONFIG_GUI | 634 #ifdef CONFIG_GUI |
625 if (use_gui) { | 635 if (use_gui) { |
748 uint8_t *yptr = src[0], *uptr = src[1], *vptr = src[2]; | 758 uint8_t *yptr = src[0], *uptr = src[1], *vptr = src[2]; |
749 int ystride = stride[0], ustride = stride[1], vstride = stride[2]; | 759 int ystride = stride[0], ustride = stride[1], vstride = stride[2]; |
750 int rem_h = h; | 760 int rem_h = h; |
751 struct TexSquare *texline = &texgrid[y / texture_height * texnumx]; | 761 struct TexSquare *texline = &texgrid[y / texture_height * texnumx]; |
752 int subtex_y = y % texture_width; | 762 int subtex_y = y % texture_width; |
763 int xs, ys; | |
764 mp_get_chroma_shift(image_format, &xs, &ys); | |
753 while (rem_h > 0) { | 765 while (rem_h > 0) { |
754 int rem_w = w; | 766 int rem_w = w; |
755 struct TexSquare *tsq = &texline[x / texture_width]; | 767 struct TexSquare *tsq = &texline[x / texture_width]; |
756 int subtex_x = x % texture_height; | 768 int subtex_x = x % texture_height; |
757 int subtex_h = rem_h; | 769 int subtex_h = rem_h; |
767 yptr, ystride, subtex_x, subtex_y, | 779 yptr, ystride, subtex_x, subtex_y, |
768 subtex_w, subtex_h, 0); | 780 subtex_w, subtex_h, 0); |
769 ActiveTexture(GL_TEXTURE1); | 781 ActiveTexture(GL_TEXTURE1); |
770 glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[0]); | 782 glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[0]); |
771 glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type, | 783 glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type, |
772 uptr, ustride, subtex_x / 2, subtex_y / 2, | 784 uptr, ustride, subtex_x >> xs, subtex_y >> ys, |
773 subtex_w / 2, subtex_h / 2, 0); | 785 subtex_w >> xs, subtex_h >> ys, 0); |
774 ActiveTexture(GL_TEXTURE2); | 786 ActiveTexture(GL_TEXTURE2); |
775 glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[1]); | 787 glBindTexture(GL_TEXTURE_2D, tsq->uvtexobjs[1]); |
776 glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type, | 788 glUploadTex(GL_TEXTURE_2D, gl_bitmap_format, gl_bitmap_type, |
777 vptr, vstride, subtex_x / 2, subtex_y / 2, | 789 vptr, vstride, subtex_x >> xs, subtex_y >> ys, |
778 subtex_w / 2, subtex_h / 2, 0); | 790 subtex_w >> xs, subtex_h >> ys, 0); |
779 subtex_x = 0; | 791 subtex_x = 0; |
780 yptr += subtex_w; | 792 yptr += subtex_w; |
781 uptr += subtex_w / 2; | 793 uptr += subtex_w >> xs; |
782 vptr += subtex_w / 2; | 794 vptr += subtex_w >> xs; |
783 tsq++; | 795 tsq++; |
784 rem_w -= subtex_w; | 796 rem_w -= subtex_w; |
785 } | 797 } |
786 subtex_y = 0; | 798 subtex_y = 0; |
787 yptr += subtex_h * ystride - w; | 799 yptr += subtex_h * ystride - w; |
788 uptr += subtex_h / 2 * ustride - w / 2; | 800 uptr += (subtex_h >> ys) * ustride - (w >> xs); |
789 vptr += subtex_h / 2 * vstride - w / 2; | 801 vptr += (subtex_h >> ys) * vstride - (w >> xs); |
790 texline += texnumx; | 802 texline += texnumx; |
791 rem_h -= subtex_h; | 803 rem_h -= subtex_h; |
792 } | 804 } |
793 ActiveTexture(GL_TEXTURE0); | 805 ActiveTexture(GL_TEXTURE0); |
794 return 0; | 806 return 0; |
795 } | 807 } |
796 | 808 |
797 static int | 809 static int |
798 draw_frame(uint8_t *src[]) | 810 draw_frame(uint8_t *src[]) |
799 { | 811 { |
800 if (image_format == IMGFMT_YV12) { | 812 if (is_yuv) { |
801 mp_msg(MSGT_VO, MSGL_ERR, "[gl2] error: draw_frame called for YV12!\n"); | 813 mp_msg(MSGT_VO, MSGL_ERR, "[gl2] error: draw_frame called for YV12!\n"); |
802 return 0; | 814 return 0; |
803 } | 815 } |
804 ImageData=(unsigned char *)src[0]; | 816 ImageData=(unsigned char *)src[0]; |
805 resetTexturePointers(ImageData); | 817 resetTexturePointers(ImageData); |
808 } | 820 } |
809 | 821 |
810 static int | 822 static int |
811 query_format(uint32_t format) | 823 query_format(uint32_t format) |
812 { | 824 { |
825 if (use_yuv && mp_get_chroma_shift(format, NULL, NULL)) | |
826 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | | |
827 VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE; | |
813 switch(format) { | 828 switch(format) { |
814 case IMGFMT_YV12: | |
815 if (use_yuv) | |
816 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | | |
817 VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE; | |
818 break; | |
819 #ifdef __APPLE__ | 829 #ifdef __APPLE__ |
820 case IMGFMT_RGB32: | 830 case IMGFMT_RGB32: |
821 #else | 831 #else |
822 case IMGFMT_RGB24: | 832 case IMGFMT_RGB24: |
823 case IMGFMT_BGR24: | 833 case IMGFMT_BGR24: |