03-videoscale-fix-negotiation.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. From 63d1316c0fd4ce22cf4a53f4aa7cb1ca16a07aa8 Mon Sep 17 00:00:00 2001
  2. From: Tim-Philipp Müller <tim.muller@collabora.co.uk>
  3. Date: Sun, 26 Feb 2012 18:19:57 +0000
  4. Subject: videoscale: fix negotiation after addition of new formats and methods
  5. Now that we no longer support all methods for all formats, we
  6. need to cater for that in the transform function: we can't
  7. transform formats not supported by the currently-selected
  8. mehod.
  9. make check, folks. It's da bomb.
  10. ---
  11. diff --git a/gst/videoscale/gstvideoscale.c b/gst/videoscale/gstvideoscale.c
  12. index 9f072a3..60dd5ff 100644
  13. --- a/gst/videoscale/gstvideoscale.c
  14. +++ b/gst/videoscale/gstvideoscale.c
  15. @@ -424,10 +424,118 @@ gst_video_scale_get_property (GObject * object, guint prop_id, GValue * value,
  16. }
  17. }
  18. +#define NEAREST (1 << GST_VIDEO_SCALE_NEAREST)
  19. +#define BILINEAR (1 << GST_VIDEO_SCALE_BILINEAR)
  20. +#define FOURTAP (1 << GST_VIDEO_SCALE_4TAP)
  21. +#define LANCZOS (1 << GST_VIDEO_SCALE_LANCZOS)
  22. +
  23. +/* or we could just do lookups via table[format] if we could be bothered.. */
  24. +static const struct
  25. +{
  26. + GstVideoFormat format;
  27. + guint8 methods;
  28. +} formats_methods_table[] = {
  29. + {
  30. + GST_VIDEO_FORMAT_RGBx, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  31. + GST_VIDEO_FORMAT_xRGB, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  32. + GST_VIDEO_FORMAT_BGRx, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  33. + GST_VIDEO_FORMAT_xBGR, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  34. + GST_VIDEO_FORMAT_RGBA, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  35. + GST_VIDEO_FORMAT_ARGB, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  36. + GST_VIDEO_FORMAT_BGRA, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  37. + GST_VIDEO_FORMAT_ABGR, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  38. + GST_VIDEO_FORMAT_AYUV, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  39. + GST_VIDEO_FORMAT_ARGB64, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  40. + GST_VIDEO_FORMAT_AYUV64, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  41. + GST_VIDEO_FORMAT_RGB, NEAREST | BILINEAR | FOURTAP}, {
  42. + GST_VIDEO_FORMAT_BGR, NEAREST | BILINEAR | FOURTAP}, {
  43. + GST_VIDEO_FORMAT_v308, NEAREST | BILINEAR | FOURTAP}, {
  44. + GST_VIDEO_FORMAT_YUY2, NEAREST | BILINEAR | FOURTAP}, {
  45. + GST_VIDEO_FORMAT_YVYU, NEAREST | BILINEAR | FOURTAP}, {
  46. + GST_VIDEO_FORMAT_UYVY, NEAREST | BILINEAR | FOURTAP}, {
  47. + GST_VIDEO_FORMAT_Y800, NEAREST | BILINEAR | FOURTAP}, {
  48. + GST_VIDEO_FORMAT_GRAY8, NEAREST | BILINEAR | FOURTAP}, {
  49. + GST_VIDEO_FORMAT_GRAY16_LE, NEAREST | BILINEAR | FOURTAP}, {
  50. + GST_VIDEO_FORMAT_GRAY16_BE, NEAREST | BILINEAR | FOURTAP}, {
  51. + GST_VIDEO_FORMAT_Y16, NEAREST | BILINEAR | FOURTAP}, {
  52. + GST_VIDEO_FORMAT_I420, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  53. + GST_VIDEO_FORMAT_YV12, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  54. + GST_VIDEO_FORMAT_Y444, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  55. + GST_VIDEO_FORMAT_Y42B, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  56. + GST_VIDEO_FORMAT_Y41B, NEAREST | BILINEAR | FOURTAP | LANCZOS}, {
  57. + GST_VIDEO_FORMAT_NV12, NEAREST | BILINEAR}, {
  58. + GST_VIDEO_FORMAT_RGB16, NEAREST | BILINEAR | FOURTAP}, {
  59. + GST_VIDEO_FORMAT_RGB15, NEAREST | BILINEAR | FOURTAP}
  60. +};
  61. +
  62. +static gboolean
  63. +gst_video_scale_format_supported_for_method (GstVideoFormat format,
  64. + GstVideoScaleMethod method)
  65. +{
  66. + int i;
  67. +
  68. + for (i = 0; i < G_N_ELEMENTS (formats_methods_table); ++i) {
  69. + if (formats_methods_table[i].format == format)
  70. + return ((formats_methods_table[i].methods & (1 << method)) != 0);
  71. + }
  72. + return FALSE;
  73. +}
  74. +
  75. +static gboolean
  76. +gst_video_scale_transform_supported (GstVideoScale * videoscale,
  77. + GstVideoScaleMethod method, GstStructure * structure)
  78. +{
  79. + const GValue *val;
  80. + GstVideoFormat fmt;
  81. + gboolean supported = TRUE;
  82. + GstStructure *s;
  83. + GstCaps *c;
  84. +
  85. + /* we support these methods for all formats */
  86. + if (method == GST_VIDEO_SCALE_NEAREST || method == GST_VIDEO_SCALE_BILINEAR)
  87. + return TRUE;
  88. +
  89. + /* we need fixed caps if we want to use gst_video_parse_caps() */
  90. + s = gst_structure_new (gst_structure_get_name (structure),
  91. + "width", G_TYPE_INT, 1, "height", G_TYPE_INT, 1, NULL);
  92. +
  93. + if ((val = gst_structure_get_value (structure, "format"))) {
  94. + gst_structure_set_value (s, "format", val);
  95. + } else {
  96. + if ((val = gst_structure_get_value (structure, "endianness")))
  97. + gst_structure_set_value (s, "endianness", val);
  98. + if ((val = gst_structure_get_value (structure, "red_mask")))
  99. + gst_structure_set_value (s, "red_mask", val);
  100. + if ((val = gst_structure_get_value (structure, "blue_mask")))
  101. + gst_structure_set_value (s, "blue_mask", val);
  102. + if ((val = gst_structure_get_value (structure, "green_mask")))
  103. + gst_structure_set_value (s, "green_mask", val);
  104. + if ((val = gst_structure_get_value (structure, "alpha_mask")))
  105. + gst_structure_set_value (s, "alpha_mask", val);
  106. + if ((val = gst_structure_get_value (structure, "depth")))
  107. + gst_structure_set_value (s, "depth", val);
  108. + if ((val = gst_structure_get_value (structure, "bpp")))
  109. + gst_structure_set_value (s, "bpp", val);
  110. + }
  111. + c = gst_caps_new_full (s, NULL);
  112. + if (!gst_video_format_parse_caps (c, &fmt, NULL, NULL)) {
  113. + GST_ERROR_OBJECT (videoscale, "couldn't parse %" GST_PTR_FORMAT, c);
  114. + } else if (!gst_video_scale_format_supported_for_method (fmt, method)) {
  115. + supported = FALSE;
  116. + }
  117. + GST_LOG_OBJECT (videoscale, "method %d %ssupported for format %d",
  118. + method, (supported) ? "" : "not ", fmt);
  119. + gst_caps_unref (c);
  120. +
  121. + return supported;
  122. +}
  123. +
  124. static GstCaps *
  125. gst_video_scale_transform_caps (GstBaseTransform * trans,
  126. GstPadDirection direction, GstCaps * caps)
  127. {
  128. + GstVideoScale *videoscale = GST_VIDEO_SCALE (trans);
  129. + GstVideoScaleMethod method;
  130. GstCaps *ret;
  131. GstStructure *structure;
  132. @@ -441,6 +549,13 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
  133. ret = gst_caps_copy (caps);
  134. structure = gst_structure_copy (gst_caps_get_structure (ret, 0));
  135. + GST_OBJECT_LOCK (videoscale);
  136. + method = videoscale->method;
  137. + GST_OBJECT_UNLOCK (videoscale);
  138. +
  139. + if (!gst_video_scale_transform_supported (videoscale, method, structure))
  140. + goto format_not_supported;
  141. +
  142. gst_structure_set (structure,
  143. "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
  144. "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
  145. @@ -452,9 +567,19 @@ gst_video_scale_transform_caps (GstBaseTransform * trans,
  146. }
  147. gst_caps_append_structure (ret, structure);
  148. +done:
  149. +
  150. GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);
  151. return ret;
  152. +
  153. +format_not_supported:
  154. + {
  155. + gst_structure_free (structure);
  156. + gst_caps_unref (ret);
  157. + ret = gst_caps_new_empty ();
  158. + goto done;
  159. + }
  160. }
  161. static gboolean
  162. --
  163. cgit v0.9.0.2-2-gbebe