Ticket #7307: studiolevel-bt709support.diff

File studiolevel-bt709support.diff, 6.3 KB (added by JYA, 10 years ago)

BT709 colorspace and studio RGB levels support patch

  • mythtv/libs/libmythtv/util-vdpau.cpp

     
    8181    deinterlacer("notset"), deinterlacing(false), currentFrameNum(-1),
    8282    needDeintRefs(false),   deintLock(QMutex::Recursive), skipChroma(0),
    8383    numRefs(0),             denoise(0.0f),          sharpen(0.0f),
    84     useColorControl(false), pipOutputSurface(0),
    85     pipAlpha(0),            pipBorder(0),
     84    useColorControl(false), colorspace(1),          studio(0),
     85    pipOutputSurface(0),    pipAlpha(0),            pipBorder(0),
    8686    pipClear(0),            pipReady(0),       pipNeedsClear(false),
    8787    vdp_flip_target(0),     vdp_flip_queue(0), vdpauDecode(false),
    8888    vdp_device(0),          errorCount(0),     errorState(kError_None),
     
    154154    if (!ok)
    155155        return ok;
    156156
    157     if (color_control)
     157    if (color_control || studio || colorspace==0 || colorspace==2)
    158158        useColorControl = InitColorControl();
    159159
    160160    return ok;
     
    17491749{
    17501750    bool ok = true;
    17511751    VdpStatus vdp_st;
     1752    static const VdpColorStandard vdp_colors[] = {0, VDP_COLOR_STANDARD_ITUR_BT_601, VDP_COLOR_STANDARD_ITUR_BT_709};
     1753    static const QString vdp_names[] = { NULL, "BT.601", "BT.709" };
    17521754
    17531755    if (!videoMixer || !useColorControl)
    17541756        return false;
    17551757
    1756     vdp_st = vdp_generate_csc_matrix(
    1757         &proCamp,
    1758         VDP_COLOR_STANDARD_ITUR_BT_601, // detect?
    1759         &cscMatrix
    1760     );
    1761     CHECK_ST
     1758    int csp = colorspace;
    17621759
     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
    17631842    VdpVideoMixerAttribute attributes[] = {
    17641843        VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX
    17651844    };
     
    21452224void VDPAUContext::ParseOptions(QString options)
    21462225{
    21472226    QStringList list = options.split(",");
     2227    static const QString vdp_names[] = { "auto", "ITU BT.601", "ITU BT.709" };
     2228
    21482229    if (list.empty())
    21492230        return;
    21502231
     
    21912272                mixerFeatures |= kVDP_FEAT_SHARPNESS;
    21922273            }
    21932274        }
     2275
     2276        if (name.contains("colorspace"))
     2277        {
     2278            int tmp = std::max(0, std::min(2, opts.toInt()));
     2279            if (tmp >= 0)
     2280            {
     2281                VERBOSE(VB_PLAYBACK, LOC + QString("Colorspace %1").arg(vdp_names[tmp]));
     2282                colorspace = tmp;
     2283            }
     2284        }
     2285
     2286        if (name.contains("studio"))
     2287        {
     2288            VERBOSE(VB_PLAYBACK, LOC +
     2289                    QString("Enabling Studio Levels [16-235]."));
     2290            studio = 1;
     2291        }
    21942292    }
    21952293}
  • mythtv/libs/libmythtv/util-vdpau.h

     
    164164    int               numRefs;
    165165    float             denoise;
    166166    float             sharpen;
    167 
     167   
    168168    bool              useColorControl;
    169169    VdpCSCMatrix      cscMatrix;
    170170    VdpProcamp        proCamp;
     171    int               colorspace;
     172    uint8_t           studio;
    171173
    172174    VdpLayer          pipLayer;
    173175    VdpOutputSurface  pipOutputSurface;