Ticket #5324: mythtv-vid-21.diff

File mythtv-vid-21.diff, 9.8 KB (added by mark.kendall@…, 16 years ago)

Add bicubic upsampling filter.

  • libs/libmythtv/openglcontext.cpp

    diff -ur -X excl mythtv-vid-20/libs/libmythtv/openglcontext.cpp mythtv-vid-21/libs/libmythtv/openglcontext.cpp
    old new  
    617617    bzero(scratch, tmp_size);
    618618
    619619    GLint check;
    620 
    621     glTexImage2D(tmp->m_type, 0, tmp->m_internal_fmt,
    622                  size.width(), size.height(), 0,
    623                  tmp->m_data_fmt , tmp->m_data_type, scratch);
     620    if (tmp->m_type == GL_TEXTURE_1D)
     621    {
     622        glTexImage1D(tmp->m_type, 0, tmp->m_internal_fmt,
     623                     size.width(), 0,
     624                     tmp->m_data_fmt , tmp->m_data_type, scratch);
     625    }
     626    else
     627    {
     628        glTexImage2D(tmp->m_type, 0, tmp->m_internal_fmt,
     629                     size.width(), size.height(), 0,
     630                     tmp->m_data_fmt , tmp->m_data_type, scratch);
     631    }
    624632    glGetTexLevelParameteriv(tmp->m_type, 0, GL_TEXTURE_WIDTH, &check);
    625633
    626634    delete [] scratch;
     
    10281036    return tmp_pbo;
    10291037}
    10301038
     1039uint OpenGLContext::CreateHelperTexture(void)
     1040{
     1041    MakeCurrent(true);
     1042
     1043    uint width = m_max_tex_size;
     1044
     1045    uint tmp_tex = CreateTexture(QSize(width, 1), QSize(width, 1),
     1046                                false,
     1047                                GL_TEXTURE_1D, GL_FLOAT,
     1048                                GL_RGBA, GL_RGBA16,
     1049                                GL_NEAREST, GL_REPEAT);
     1050
     1051    if (!tmp_tex)
     1052    {
     1053        DeleteTexture(tmp_tex);
     1054        return 0;
     1055    }
     1056
     1057    float *buf = NULL;
     1058    buf = new float[m_priv->m_textures[tmp_tex].m_data_size];
     1059    float *ref = buf;
     1060
     1061    for (uint i = 0; i < width; i++)
     1062    {
     1063        float x = (((float)i) + 0.5f) / (float)width;
     1064        store_bicubic_weights(x, ref);
     1065        ref += 4;
     1066    }
     1067    store_bicubic_weights(0, buf);
     1068    store_bicubic_weights(1, &buf[(width - 1) << 2]);
     1069
     1070    EnableTextures(tmp_tex);
     1071    glBindTexture(m_priv->m_textures[tmp_tex].m_type, tmp_tex);
     1072    glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16, width, 0, GL_RGBA, GL_FLOAT, buf);
     1073
     1074    VERBOSE(VB_PLAYBACK, LOC +
     1075            QString("Created bicubic helper texture (%1 samples)")
     1076            .arg(width));
     1077
     1078    delete [] buf;
     1079
     1080    MakeCurrent(false);
     1081
     1082    return tmp_tex;
     1083}
     1084
    10311085int OpenGLContext::SetPictureAttribute(
    10321086    PictureAttribute attribute, int newValue)
    10331087{
  • libs/libmythtv/openglcontext.h

    diff -ur -X excl mythtv-vid-20/libs/libmythtv/openglcontext.h mythtv-vid-21/libs/libmythtv/openglcontext.h
    old new  
    110110    int SetPictureAttribute(PictureAttribute attributeType, int newValue);
    111111    PictureAttributeSupported GetSupportedPictureAttributes(void) const;
    112112    void SetColourParams(void);
     113    uint CreateHelperTexture(void);
    113114
    114115  private:
    115116    void Init2DState(void);
     
    192193    PictureAttributeSupported GetSupportedPictureAttributes(void) const
    193194        { return kPictureAttributeSupported_None; }
    194195    void SetColourParams(void);
     196    uint CreateHelperTexture(void);
    195197};
    196198
    197199#endif //!USING_OPENGL
  • libs/libmythtv/openglvideo.cpp

    diff -ur -X excl mythtv-vid-20/libs/libmythtv/openglvideo.cpp mythtv-vid-21/libs/libmythtv/openglvideo.cpp
    old new  
    4444    inputTextureSize(0,0),    currentFrameNum(0),
    4545    inputUpdated(false),     
    4646    textureRects(false),      textureType(GL_TEXTURE_2D),
     47    helperTexture(0),         defaultResize(kGLFilterResize),
    4748    convertSize(0,0),         convertBuf(NULL),
    4849
    4950    videoResize(false),       videoResizeRect(0,0,0,0),
     
    6263{
    6364    ShutDownYUV2RGB();
    6465
     66    if (helperTexture)
     67        gl_context->DeleteTexture(helperTexture);
     68    helperTexture = 0;
     69
    6570    DeleteTextures(&inputTextures);
    6671    DeleteTextures(&referenceTextures);
    6772
     
    110115    inputUpdated          = false;
    111116    gl_letterbox_colour   = letterbox_colour;
    112117
    113     gl_context->GetTextureType(textureType, textureRects);
     118    if (defaultResize != kGLFilterBicubic)
     119        gl_context->GetTextureType(textureType, textureRects);
    114120
    115121    SetViewPort(display_visible_rect.size());
    116122
     
    192198{
    193199    bool resize =  ((video_dim.height() < display_video_rect.height()) ||
    194200                    (video_dim.width()  <  display_video_rect.width()));
     201    resize &= !filters.count(kGLFilterResize);
     202    resize &= !filters.count(kGLFilterBicubic);
    195203
    196     if (resize && !filters.count(kGLFilterResize))
    197         AddFilter(kGLFilterResize);
    198     else if (!resize && filters.count(kGLFilterResize) &&
    199              !filters.count(kGLFilterYUV2RGBA))
    200         RemoveFilter(kGLFilterResize);
     204    if (resize)
     205        AddFilter(defaultResize);
    201206
    202207    glfilt_map_t::reverse_iterator it;
    203208
     
    303308    temp->numInputs = 1;
    304309    GLuint program = 0;
    305310
     311    if (filter == kGLFilterBicubic)
     312    {
     313        if (helperTexture)
     314            gl_context->DeleteTexture(helperTexture);
     315 
     316        helperTexture = gl_context->CreateHelperTexture();
     317        if (!helperTexture)
     318            success = false;
     319    }
     320
    306321    if (filter != kGLFilterNone && filter != kGLFilterResize)
    307322    {
    308323        program = AddFragmentProgram(filter);
     
    880895            }
    881896        }
    882897
     898        if (helperTexture && type == kGLFilterBicubic)
     899        {
     900            glActiveTexture(GL_TEXTURE0 + active_tex);
     901            glBindTexture(GL_TEXTURE_1D/*N.B.*/, helperTexture);
     902        }
     903
    883904        // enable fragment program and set any environment variables
    884905        if ((type != kGLFilterNone) && (type != kGLFilterResize))
    885906        {
     
    10211042        ret = kGLFilterYUV2RGBA;
    10221043    else if (filter.contains("resize"))
    10231044        ret = kGLFilterResize;
     1045    else if (filter.contains("bicubic"))
     1046        ret = kGLFilterBicubic;
    10241047
    10251048    return ret;
    10261049}
     
    10381061            return "osd";
    10391062        case kGLFilterResize:
    10401063            return "resize";
     1064        case kGLFilterBicubic:
     1065            return "bicubic";
    10411066    }
    10421067
    10431068    return "";
     
    14101435"CMP res, prev, spred1, current;\n"
    14111436};
    14121437
     1438static const QString bicubic =
     1439"TEMP coord, coord2, cdelta, parmx, parmy, a, b, c, d;\n"
     1440"MAD coord.xy, fragment.texcoord[0], {%6, %7}, {0.5, 0.5};\n"
     1441"TEX parmx, coord.x, texture[1], 1D;\n"
     1442"TEX parmy, coord.y, texture[1], 1D;\n"
     1443"MUL cdelta.xz, parmx.rrgg, {-%5, 0, %5, 0};\n"
     1444"MUL cdelta.yw, parmy.rrgg, {0, -%3, 0, %3};\n"
     1445"ADD coord, fragment.texcoord[0].xyxy, cdelta.xyxw;\n"
     1446"ADD coord2, fragment.texcoord[0].xyxy, cdelta.zyzw;\n"
     1447"TEX a, coord.xyxy, texture[0], 2D;\n"
     1448"TEX b, coord.zwzw, texture[0], 2D;\n"
     1449"TEX c, coord2.xyxy, texture[0], 2D;\n"
     1450"TEX d, coord2.zwzw, texture[0], 2D;\n"
     1451"LRP a, parmy.b, a, b;\n"
     1452"LRP c, parmy.b, c, d;\n"
     1453"LRP result.color, parmx.b, a, c;\n";
     1454
    14131455QString OpenGLVideo::GetProgramString(OpenGLFilterType name,
    14141456                                      QString deint, FrameScanType field)
    14151457{
     
    14871529        case kGLFilterResize:
    14881530            break;
    14891531
     1532        case kGLFilterBicubic:
     1533 
     1534            ret += bicubic;
     1535            break;
     1536
    14901537        default:
    14911538            VERBOSE(VB_PLAYBACK, LOC_ERR + "Unknown fragment program.");
    14921539            break;
     
    14971544
    14981545    float lineHeight = 1.0f;
    14991546    float colWidth   = 1.0f;
     1547    QSize fb_size = GetTextureSize(video_dim);
    15001548
    15011549    if (!textureRects &&
    15021550       (inputTextureSize.height() > 0))
     
    15111559    ret.replace("%3", temp.setNum(lineHeight, 'f', 8));
    15121560    ret.replace("%4", temp.setNum(lineHeight * 2.0, 'f', 8));
    15131561    ret.replace("%5", temp.setNum(colWidth, 'f', 8));
     1562    ret.replace("%6", temp.setNum((float)fb_size.width(), 'f', 1));
     1563    ret.replace("%7", temp.setNum((float)fb_size.height(), 'f', 1));
    15141564
    15151565    ret += "END";
    15161566
  • libs/libmythtv/openglvideo.h

    diff -ur -X excl mythtv-vid-20/libs/libmythtv/openglvideo.h mythtv-vid-21/libs/libmythtv/openglvideo.h
    old new  
    2121
    2222    // Frame scaling/resizing filters
    2323    kGLFilterResize,
     24    kGLFilterBicubic,
    2425};
    2526
    2627enum DisplayBuffer
     
    127128    bool           inputUpdated;
    128129    bool           textureRects;
    129130    uint           textureType;
     131    uint           helperTexture;
     132    OpenGLFilterType defaultResize;
    130133
    131134    QSize            convertSize;
    132135    unsigned char   *convertBuf;
  • libs/libmythtv/util-opengl.cpp

    diff -ur -X excl mythtv-vid-20/libs/libmythtv/util-opengl.cpp mythtv-vid-21/libs/libmythtv/util-opengl.cpp
    old new  
    911911        dst_1 += dwrap; dst_2 += dwrap; dst_3 += dwrap; dst_4 += dwrap;
    912912    }
    913913}
     914
     915void store_bicubic_weights(float x, float *dst)
     916{
     917    float w0 = (((-1 * x + 3) * x - 3) * x + 1) / 6;
     918    float w1 = ((( 3 * x - 6) * x + 0) * x + 4) / 6;
     919    float w2 = (((-3 * x + 3) * x + 3) * x + 1) / 6;
     920    float w3 = ((( 1 * x + 0) * x + 0) * x + 0) / 6;
     921    *dst++ = 1 + x - w1 / (w0 + w1);
     922    *dst++ = 1 - x + w3 / (w2 + w3);
     923    *dst++ = w0 + w1;
     924    *dst++ = 0;
     925}
  • libs/libmythtv/util-opengl.h

    diff -ur -X excl mythtv-vid-20/libs/libmythtv/util-opengl.h mythtv-vid-21/libs/libmythtv/util-opengl.h
    old new  
    128128                 const int *pitches,
    129129                 const QSize size);
    130130
     131void store_bicubic_weights(float x, float *dst);
     132
    131133__GLXextFuncPtr get_gl_proc_address(const QString &procName);
    132134
    133135int get_gl_texture_rect_type(const QString &extensions);