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(&params); 596 glSetupYUVConversion(&params);
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: