Ticket #7307: studiolevel-bt709support.diff

File studiolevel-bt709support.diff, 6.3 KB (added by jyavenard, 3 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;