| | 1760 | // Try to detect best color standard based on the resolution |
| | 1761 | // Use BT_601 if SD, BT_709 if HD |
| | 1762 | if (!colorspace) |
| | 1763 | { |
| | 1764 | csp = videoSize.width() >= 1280 || videoSize.height() > 576 ? 2 : 1; |
| | 1765 | } |
| | 1766 | |
| | 1767 | VERBOSE(VB_PLAYBACK, LOC + QString("Updating CSC matrix for ITU %1 (%2 levels)") |
| | 1768 | .arg(vdp_names[csp]) |
| | 1769 | .arg(studio ? "studio" : "PC")); |
| | 1770 | |
| | 1771 | if (studio) |
| | 1772 | { |
| | 1773 | static const float color_coeffs[][3] = { { 0, 0, 0 }, |
| | 1774 | { 0.299, 0.587, 0.114 }, |
| | 1775 | { 0.2125, 0.7154, 0.0721 } }; |
| | 1776 | float uvcos = proCamp.saturation * cos(proCamp.hue); |
| | 1777 | float uvsin = proCamp.saturation * sin(proCamp.hue); |
| | 1778 | float Kr, Kg, Kb; |
| | 1779 | int rgbmin = 16; |
| | 1780 | int rgbr = 235-16; |
| | 1781 | |
| | 1782 | Kr = color_coeffs[csp][0]; |
| | 1783 | Kg = color_coeffs[csp][1]; |
| | 1784 | Kb = color_coeffs[csp][2]; |
| | 1785 | |
| | 1786 | /* |
| | 1787 | |
| | 1788 | BT.709 PC levels |
| | 1789 | 1.164400 0.000000 1.792700 -0.972926 |
| | 1790 | 1.164400 -0.213200 -0.532900 0.301453 |
| | 1791 | 1.164400 2.112400 0.000000 -1.133402 |
| | 1792 | BT.601 PC levels |
| | 1793 | 1.164400 0.000000 1.596000 -0.874190 |
| | 1794 | 1.164400 -0.391800 -0.813000 0.531702 |
| | 1795 | 1.164400 2.017200 0.000000 -1.085616 |
| | 1796 | |
| | 1797 | |
| | 1798 | See: |
| | 1799 | http://avisynth.org/mediawiki/Color_conversions |
| | 1800 | and http://en.wikipedia.org/wiki/YCbCr for more information. |
| | 1801 | |
| | 1802 | rgbr/219 0 (1-Kr)*rgbr/112 -16/219 - 128/112*(1-Kr) + rgbmin/255 |
| | 1803 | rgbr/219 -(rgbr/112)*(1-Kb)*Kb/Kg -(rgbr/112)*(1-Kr)*Kr/Kg -16/219 + 128/112*(1-Kb)*Kb/Kg + 128/112*(1-Kr)*Kr/Kg + rgbmin/255 |
| | 1804 | rgbr/219 (rgbr/112)*(1-Kb) 0 -16/219 - 128/112*(1-Kb) + rgbmin/255 |
| | 1805 | |
| | 1806 | */ |
| | 1807 | |
| | 1808 | #define COL_Y 0 |
| | 1809 | #define COL_U 1 |
| | 1810 | #define COL_V 2 |
| | 1811 | #define COL_C 3 |
| | 1812 | float uv_coeffs[3][2] = { |
| | 1813 | { 0.000, (rgbr/112.0)*(1-Kr) }, |
| | 1814 | {-(rgbr/112.0)*(1-Kb)*Kb/Kg, -(rgbr/112.0)*(1-Kr)*Kr/Kg }, |
| | 1815 | { (rgbr/112.0)*(1-Kb), 0.000 } |
| | 1816 | }; |
| | 1817 | |
| | 1818 | for (int i = 0; i < 3; i++) |
| | 1819 | { |
| | 1820 | cscMatrix[i][COL_C] = proCamp.brightness; |
| | 1821 | cscMatrix[i][COL_Y] = rgbr * proCamp.contrast / 219; |
| | 1822 | cscMatrix[i][COL_C] += (-16 / 255.0) * cscMatrix[i][COL_Y]; |
| | 1823 | cscMatrix[i][COL_U] = uv_coeffs[i][0] * uvcos + uv_coeffs[i][1] * uvsin; |
| | 1824 | cscMatrix[i][COL_C] += (-128 / 255.0) * cscMatrix[i][COL_U]; |
| | 1825 | cscMatrix[i][COL_V] = uv_coeffs[i][0] * uvsin + uv_coeffs[i][1] * uvcos; |
| | 1826 | cscMatrix[i][COL_C] += (-128 / 255.0) * cscMatrix[i][COL_V]; |
| | 1827 | cscMatrix[i][COL_C] += rgbmin / 255.0; |
| | 1828 | // this "centers" contrast control so that e.g. a contrast of 0 |
| | 1829 | // leads to a grey image, not a black one |
| | 1830 | cscMatrix[i][COL_C] += 0.5 - proCamp.contrast / 2.0; |
| | 1831 | } |
| | 1832 | } |
| | 1833 | else |
| | 1834 | { |
| | 1835 | vdp_st = vdp_generate_csc_matrix( |
| | 1836 | &proCamp, |
| | 1837 | vdp_colors[csp], |
| | 1838 | &cscMatrix); |
| | 1839 | CHECK_ST |
| | 1840 | } |
| | 1841 | |