Ticket #5324: mythtv-vid-18.diff

File mythtv-vid-18.diff, 48.3 KB (added by mark.kendall@…, 4 years ago)

Re-write of texture handling. Default to packing all video textures, even if we don't have PixelBufferObjects? (still as fast as existing code and makes fragment program code much easier to handle). Much tighter control over texture properties - needed for bicubic filter. Fixes some FrameBufferObject? instability.

  • libs/libmythtv/frame.h

    diff -ur -X excl mythtv-vid-17/libs/libmythtv/frame.h mythtv-vid-18/libs/libmythtv/frame.h
    old new  
    2121    FMT_ARGB32, 
    2222    FMT_RGBA32, 
    2323    FMT_YUV422P, 
    24     FMT_ALPHA, 
     24    FMT_BGRA, 
    2525} VideoFrameType; 
    2626 
    2727typedef struct VideoFrame_ 
  • libs/libmythtv/openglcontext.cpp

    diff -ur -X excl mythtv-vid-17/libs/libmythtv/openglcontext.cpp mythtv-vid-18/libs/libmythtv/openglcontext.cpp
    old new  
    44 
    55#include "util-opengl.h" 
    66 
     7 
    78#define LOC QString("GLCtx: ") 
    89#define LOC_ERR QString("GLCtx, Error: ") 
    910 
     
    1920        m_ctx->MakeCurrent(false); 
    2021} 
    2122 
     23class MythGLTexture 
     24{ 
     25  public: 
     26    MythGLTexture() : 
     27        m_type(GL_TEXTURE_2D), m_data(NULL), m_data_size(0), 
     28        m_data_type(GL_UNSIGNED_BYTE), m_data_fmt(GL_BGRA), 
     29        m_internal_fmt(GL_RGBA8), m_pbo(0), 
     30        m_filter(GL_LINEAR), m_wrap(GL_CLAMP_TO_EDGE), 
     31        m_size(0,0), m_vid_size(0,0) 
     32    { 
     33    } 
     34 
     35    ~MythGLTexture() 
     36    { 
     37    } 
     38 
     39    GLuint  m_type; 
     40    unsigned char *m_data; 
     41    uint    m_data_size; 
     42    GLuint  m_data_type; 
     43    GLuint  m_data_fmt; 
     44    GLuint  m_internal_fmt; 
     45    GLuint  m_pbo; 
     46    GLuint  m_filter; 
     47    GLuint  m_wrap; 
     48    QSize   m_size; 
     49    QSize   m_vid_size; 
     50}; 
     51 
    2252class PrivateContext 
    2353{ 
    2454  public: 
    2555    PrivateContext() : 
    2656        m_glx_fbconfig(0), m_gl_window(0), m_glx_window(0), 
    27         m_glx_context(NULL), 
    28         m_texture_type(GL_TEXTURE_2D), m_textures_enabled(false), 
     57        m_glx_context(NULL), m_texture_type(0), 
    2958        m_vis_info(NULL), m_attr_list(NULL) 
    3059    { 
    3160    } 
     
    3968    GLXWindow    m_glx_window; 
    4069    GLXContext   m_glx_context; 
    4170    int          m_texture_type; 
    42     bool         m_textures_enabled; 
    4371    XVisualInfo *m_vis_info; 
    4472    int const   *m_attr_list; 
    4573 
    46     vector<GLuint> m_textures; 
     74    map<GLuint, MythGLTexture> m_textures; 
    4775    vector<GLuint> m_programs; 
    4876    vector<GLuint> m_framebuffers; 
    49     vector<GLuint> m_pbos; 
    5077    GLuint         m_fence; 
    5178}; 
    5279 
     
    75102        DeletePrograms(); 
    76103        DeleteTextures(); 
    77104        DeleteFrameBuffers(); 
    78         DeletePBOs(); 
    79105 
    80106        Flush(true); 
    81107 
     
    265291        MakeCurrent(false); 
    266292    } 
    267293 
    268     int tex_type = get_gl_texture_rect_type(m_extensions); 
    269     m_priv->m_texture_type = (tex_type) ? tex_type : m_priv->m_texture_type; 
    270  
    271294    m_ext_supported = 
    272         ((tex_type) ? kGLExtRect : 0) | 
     295        ((get_gl_texture_rect_type(m_extensions)) ? kGLExtRect : 0) | 
    273296        ((has_gl_fragment_program_support(m_extensions)) ? 
    274297         kGLExtFragProg : 0) | 
    275298        ((has_gl_pixelbuffer_object_support(m_extensions)) ? 
     
    380403} 
    381404 
    382405// locking ok 
    383 void OpenGLContext::EnableTextures(void) 
     406void OpenGLContext::EnableTextures(uint tex, uint tex_type) 
    384407{ 
    385     if (!m_priv->m_textures_enabled) 
     408    MakeCurrent(true); 
     409 
     410    int type = tex ? m_priv->m_textures[tex].m_type : tex_type; 
     411 
     412    if (type != m_priv->m_texture_type) 
    386413    { 
    387         m_priv->m_textures_enabled = true; 
     414        if (m_priv->m_texture_type) 
     415        { 
     416            glDisable(m_priv->m_texture_type); 
     417        } 
     418        glEnable(type); 
     419        m_priv->m_texture_type = type; 
     420    } 
    388421 
    389         MakeCurrent(true); 
    390         glEnable(GetTextureType()); 
    391         MakeCurrent(false); 
     422    MakeCurrent(false); 
     423} 
     424 
     425void OpenGLContext::UpdateTexture(uint tex, 
     426                       const unsigned char *buf, 
     427                       const int *offsets, 
     428                       const int *pitches, 
     429                       VideoFrameType fmt, 
     430                       bool interlaced, 
     431                       const unsigned char* alpha) 
     432{ 
     433    MakeCurrent(true); 
     434 
     435    MythGLTexture *tmp_tex = &m_priv->m_textures[tex]; 
     436    QSize size = tmp_tex->m_vid_size; 
     437 
     438    EnableTextures(tex); 
     439    glBindTexture(tmp_tex->m_type, tex); 
     440 
     441    if (tmp_tex->m_pbo) 
     442    { 
     443        void *pboMemory; 
     444 
     445        gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, tmp_tex->m_pbo); 
     446        gMythGLBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 
     447                             tmp_tex->m_data_size, NULL, GL_STREAM_DRAW); 
     448 
     449        pboMemory = gMythGLMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 
     450                                        GL_WRITE_ONLY); 
     451 
     452        if (FMT_BGRA == fmt) 
     453        { 
     454            memcpy(pboMemory, buf, tmp_tex->m_data_size); 
     455        } 
     456        else if (interlaced) 
     457        { 
     458            pack_yv12interlaced(buf, (unsigned char *)pboMemory, 
     459                                offsets, pitches, size); 
     460        } 
     461        else 
     462        { 
     463            pack_yv12alpha(buf, (unsigned char *)pboMemory, 
     464                           offsets, pitches, size, alpha); 
     465        } 
     466 
     467        gMythGLUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); 
     468 
     469        glTexSubImage2D(tmp_tex->m_type, 0, 0, 0, size.width(), size.height(), 
     470                        tmp_tex->m_data_fmt, tmp_tex->m_data_type, 0); 
     471 
     472        gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 
    392473    } 
     474    else 
     475    { 
     476        if (!tmp_tex->m_data) 
     477        { 
     478            unsigned char *scratch = new unsigned char[tmp_tex->m_data_size]; 
     479            if (scratch) 
     480            { 
     481                bzero(scratch, tmp_tex->m_data_size); 
     482                tmp_tex->m_data = scratch; 
     483            } 
     484        } 
     485 
     486        if (tmp_tex->m_data) 
     487        { 
     488            const unsigned char *tmp = tmp_tex->m_data; 
     489 
     490            if (FMT_BGRA == fmt) 
     491            { 
     492                tmp = buf; 
     493            } 
     494            else if (interlaced) 
     495            { 
     496                pack_yv12interlaced(buf, tmp, 
     497                                    offsets, pitches, size); 
     498            } 
     499            else 
     500            { 
     501                pack_yv12alpha(buf, tmp, offsets, 
     502                               pitches, size, alpha); 
     503            } 
     504 
     505            glTexSubImage2D(tmp_tex->m_type, 0, 0, 0, 
     506                            size.width(), size.height(), 
     507                            tmp_tex->m_data_fmt, tmp_tex->m_data_type, 
     508                            tmp); 
     509        } 
     510    } 
     511 
     512    MakeCurrent(false); 
    393513} 
    394514 
    395515// locking ok 
    396 uint OpenGLContext::CreateTexture(void) 
     516uint OpenGLContext::CreateTexture(QSize tot_size, QSize vid_size, 
     517                                  bool use_pbo, 
     518                                  uint type, uint data_type, 
     519                                  uint data_fmt, uint internal_fmt, 
     520                                  uint filter, uint wrap) 
    397521{ 
     522    if ((uint)tot_size.width() > m_max_tex_size || 
     523        (uint)tot_size.height() > m_max_tex_size) 
     524        return 0; 
     525 
    398526    MakeCurrent(true); 
    399527 
     528    EnableTextures(0, type); 
     529 
    400530    GLuint tex; 
    401531    glGenTextures(1, &tex); 
    402     SetupTextureFilters(tex, GL_LINEAR); 
    403     m_priv->m_textures.push_back(tex); 
     532    glBindTexture(type, tex); 
     533 
     534    if (tex) 
     535    { 
     536        MythGLTexture *texture = new MythGLTexture(); 
     537        texture->m_type = type; 
     538        texture->m_data_type = data_type; 
     539        texture->m_data_fmt = data_fmt; 
     540        texture->m_internal_fmt = internal_fmt; 
     541        texture->m_size = tot_size; 
     542        texture->m_vid_size = vid_size; 
     543        texture->m_data_size = GetBufferSize(vid_size, data_fmt, data_type); 
     544        m_priv->m_textures[tex] = *texture; 
     545 
     546        if (ClearTexture(tex) && m_priv->m_textures[tex].m_data_size) 
     547        { 
     548            SetTextureFilters(tex, filter, wrap); 
     549            if (use_pbo) 
     550                m_priv->m_textures[tex].m_pbo = CreatePBO(tex); 
     551        } 
     552        else 
     553        { 
     554            DeleteTexture(tex); 
     555            tex = 0; 
     556        } 
     557 
     558        delete texture; 
     559    } 
    404560 
    405561    Flush(true); 
    406562 
     
    409565    return tex; 
    410566} 
    411567 
     568uint OpenGLContext::GetBufferSize(QSize size, uint fmt, uint type) 
     569{ 
     570    uint bytes; 
     571    uint bpp; 
     572 
     573    switch (fmt) 
     574    { 
     575        case GL_BGRA: 
     576        case GL_RGBA: 
     577            bpp = 4; 
     578            break; 
     579        default: 
     580            bpp =0; 
     581    } 
     582 
     583    switch (type) 
     584    { 
     585        case GL_UNSIGNED_BYTE: 
     586            bytes = sizeof(GLubyte); 
     587            break; 
     588        case GL_FLOAT: 
     589            bytes = sizeof(GLfloat); 
     590            break; 
     591        default: 
     592            bytes = 0; 
     593    } 
     594 
     595    if (!bpp || !bytes || size.width() < 1 || size.height() < 1) 
     596        return 0; 
     597 
     598    return size.width() * size.height() * bpp * bytes; 
     599} 
     600 
    412601// locking ok 
    413 bool OpenGLContext::SetupTexture(const QSize &size, uint tex, int filt) 
     602bool OpenGLContext::ClearTexture(uint tex) 
    414603{ 
    415     unsigned char *scratch = 
    416         new unsigned char[(size.width() * size.height() * 4) + 128]; 
     604    MythGLTexture *tmp = &m_priv->m_textures[tex]; 
     605    QSize size = tmp->m_size; 
     606 
     607    uint tmp_size = GetBufferSize(size, tmp->m_data_fmt, tmp->m_data_type); 
     608 
     609    if (!tmp_size) 
     610        return false; 
     611 
     612    unsigned char *scratch = new unsigned char[tmp_size]; 
    417613 
    418614    if (!scratch) 
    419615        return false; 
    420616 
    421     bzero(scratch, size.width() * size.height() * 4); 
     617    bzero(scratch, tmp_size); 
    422618 
    423619    GLint check; 
    424620 
    425     MakeCurrent(true); 
    426     SetupTextureFilters(tex, filt); 
    427     glTexImage2D(GetTextureType(), 0, GL_RGBA8, size.width(), size.height(), 
    428                  0, GL_RGB , GL_UNSIGNED_BYTE, scratch); 
    429     glGetTexLevelParameteriv(GetTextureType(), 0, GL_TEXTURE_WIDTH, &check); 
    430     MakeCurrent(false); 
     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); 
     624    glGetTexLevelParameteriv(tmp->m_type, 0, GL_TEXTURE_WIDTH, &check); 
    431625 
    432626    delete [] scratch; 
    433627 
     
    435629} 
    436630 
    437631// locking ok 
    438 void OpenGLContext::SetupTextureFilters(uint tex, int filt) 
     632void OpenGLContext::SetTextureFilters(uint tex, uint filt, uint wrap) 
    439633{ 
     634    if (!m_priv->m_textures.count(tex)) 
     635        return; 
     636 
    440637    MakeCurrent(true); 
    441     glBindTexture(GetTextureType(), tex); 
    442     glTexParameteri(GetTextureType(), GL_TEXTURE_MIN_FILTER, filt); 
    443     glTexParameteri(GetTextureType(), GL_TEXTURE_MAG_FILTER, filt); 
    444     glTexParameteri(GetTextureType(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    445     glTexParameteri(GetTextureType(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
     638 
     639    EnableTextures(tex); 
     640 
     641    m_priv->m_textures[tex].m_filter = filt; 
     642    m_priv->m_textures[tex].m_wrap = wrap; 
     643 
     644    uint type = m_priv->m_textures[tex].m_type; 
     645 
     646    glBindTexture(type, tex); 
     647    glTexParameteri(type, GL_TEXTURE_MIN_FILTER, filt); 
     648    glTexParameteri(type, GL_TEXTURE_MAG_FILTER, filt); 
     649    glTexParameteri(type, GL_TEXTURE_WRAP_S, wrap); 
     650    if (type != GL_TEXTURE_1D) 
     651        glTexParameteri(type, GL_TEXTURE_WRAP_T, wrap); 
     652 
    446653    MakeCurrent(false); 
    447654} 
    448655 
    449656// locking ok 
    450657void OpenGLContext::DeleteTexture(uint tex) 
    451658{ 
     659    if (!m_priv->m_textures.count(tex)) 
     660        return; 
     661 
    452662    MakeCurrent(true); 
    453663 
    454     vector<GLuint>::iterator it; 
    455     for (it = m_priv->m_textures.begin(); it !=m_priv->m_textures.end(); it++) 
     664    GLuint gltex = tex; 
     665    glDeleteTextures(1, &gltex); 
     666 
     667    if (m_priv->m_textures[tex].m_data) 
    456668    { 
    457         if (*(it) == tex) 
    458         { 
    459             GLuint gltex = tex; 
    460             glDeleteTextures(1, &gltex); 
    461             m_priv->m_textures.erase(it); 
    462             break; 
    463         } 
     669        delete m_priv->m_textures[tex].m_data; 
     670    } 
     671 
     672    if (m_priv->m_textures[tex].m_pbo) 
     673    { 
     674        gMythGLDeleteBuffersARB(1, &(m_priv->m_textures[tex].m_pbo)); 
    464675    } 
    465676 
     677    m_priv->m_textures.erase(tex); 
     678 
    466679    Flush(true); 
    467680 
    468681    MakeCurrent(false); 
     
    471684// locking ok 
    472685void OpenGLContext::DeleteTextures(void) 
    473686{ 
    474     vector<GLuint>::iterator it; 
     687    map<GLuint, MythGLTexture>::iterator it; 
    475688    for (it = m_priv->m_textures.begin(); it !=m_priv->m_textures.end(); it++) 
    476         glDeleteTextures(1, &(*(it))); 
     689    { 
     690        GLuint gltex = it->first; 
     691        glDeleteTextures(1, &gltex); 
     692 
     693        if (it->second.m_data) 
     694        { 
     695            delete it->second.m_data; 
     696        } 
     697 
     698        if (it->second.m_pbo) 
     699        { 
     700            gltex = it->second.m_pbo; 
     701            gMythGLDeleteBuffersARB(1, &gltex); 
     702        } 
     703    } 
    477704    m_priv->m_textures.clear(); 
    478705 
    479706    Flush(true); 
    480707} 
    481708 
    482 int OpenGLContext::GetTextureType(void) const 
     709void OpenGLContext::GetTextureType(uint &current, bool &rect) 
    483710{ 
    484     return m_priv->m_texture_type; 
     711    uint type = get_gl_texture_rect_type(m_extensions); 
     712    if (type) 
     713    { 
     714        rect = true; 
     715        current = type; 
     716        return; 
     717    } 
     718 
     719    rect = false; 
     720    return; 
    485721} 
    486722 
    487723// locking ok 
     
    585821} 
    586822 
    587823// locking ok 
    588 bool OpenGLContext::CreateFrameBuffer(uint &fb, uint tex, const QSize &size) 
     824bool OpenGLContext::CreateFrameBuffer(uint &fb, uint tex) 
    589825{ 
     826    if (!m_priv->m_textures.count(tex)) 
     827        return false; 
     828 
     829    MythGLTexture *tmp = &m_priv->m_textures[tex]; 
     830    QSize size = tmp->m_size; 
    590831    GLuint glfb; 
    591832 
    592833    MakeCurrent(true); 
    593834    glCheck(); 
    594835 
    595     SetupTextureFilters(tex, GL_LINEAR); 
     836    EnableTextures(tex); 
    596837 
    597838    glPushAttrib(GL_VIEWPORT_BIT); 
    598839    glViewport(0, 0, size.width(), size.height()); 
    599840    gMythGLGenFramebuffersEXT(1, &glfb); 
    600841    gMythGLBindFramebufferEXT(GL_FRAMEBUFFER_EXT, glfb); 
    601     glBindTexture(GetTextureType(), tex); 
    602     glTexImage2D(GetTextureType(), 0, GL_RGBA8, 
     842    glBindTexture(tmp->m_type, tex); 
     843    glTexImage2D(tmp->m_type, 0, tmp->m_internal_fmt, 
    603844                 (GLint) size.width(), (GLint) size.height(), 0, 
    604                  GL_RGB, GL_UNSIGNED_BYTE, NULL); 
     845                 tmp->m_data_fmt, tmp->m_data_type, NULL); 
    605846    gMythGLFramebufferTexture2DEXT( 
    606847        GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 
    607         GetTextureType(), tex, 0); 
     848        tmp->m_type, tex, 0); 
    608849 
    609850    GLenum status; 
    610851    status = gMythGLCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 
     
    735976    glDisable(GL_DEPTH_TEST); 
    736977    glDepthMask(GL_FALSE); 
    737978    glDisable(GL_CULL_FACE); 
    738  
    739     EnableTextures();; 
    740  
    741979    glShadeModel(GL_FLAT); 
    742980    glDisable(GL_POLYGON_SMOOTH); 
    743981    glDisable(GL_LINE_SMOOTH); 
     
    7681006    MakeCurrent(false); 
    7691007} 
    7701008 
    771 void OpenGLContext::UpdatePBO(uint tex, uint pbo, 
    772                              const VideoFrame *frame, 
    773                              const unsigned char *alpha) 
     1009uint OpenGLContext::CreatePBO(uint tex) 
    7741010{ 
    775     MakeCurrent(true); 
    776  
    777     void *pboMemory; 
    778     uint tex_size = frame->width * frame->height * 4; 
     1011    if (!m_priv->m_textures.count(tex)) 
     1012        return 0; 
    7791013 
    780     glBindTexture(GetTextureType(), tex); 
    781     gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); 
    782     gMythGLBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, 
    783                          tex_size, NULL, GL_STREAM_DRAW); 
    784  
    785     pboMemory = gMythGLMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 
    786                                     GL_WRITE_ONLY); 
    787  
    788     if (frame->interlaced_frame) 
    789     { 
    790         pack_yv12interlaced(frame->buf, (unsigned char *)pboMemory, 
    791                             frame->offsets, frame->pitches, 
    792                             QSize(frame->width, frame->height)); 
    793     } 
    794     else 
    795     { 
    796         pack_yv12alpha(frame->buf, (unsigned char *)pboMemory, 
    797                        frame->offsets, frame->pitches, 
    798                        QSize(frame->width, frame->height), alpha); 
    799     } 
    800  
    801     gMythGLUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); 
    802  
    803     glTexSubImage2D(GetTextureType(), 0, 0, 0, frame->width, frame->height, 
    804                     GL_BGRA, GL_UNSIGNED_BYTE, 0); 
    805  
    806     gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 
    807  
    808     MakeCurrent(false); 
    809 } 
    810  
    811  
    812 uint OpenGLContext::CreatePBO(QSize size) 
    813 { 
    814     MakeCurrent(true); 
     1014    MythGLTexture *tmp = &m_priv->m_textures[tex]; 
    8151015 
    8161016    gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 
    817     glTexImage2D(GetTextureType(), 0, GL_RGBA8, size.width(), size.height(), 
    818                  0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); 
     1017    glTexImage2D(tmp->m_type, 0, tmp->m_internal_fmt, 
     1018                 tmp->m_size.width(), tmp->m_size.height(), 0, 
     1019                 tmp->m_data_fmt, tmp->m_data_type, NULL); 
    8191020 
    8201021    GLuint tmp_pbo; 
    8211022    gMythGLGenBuffersARB(1, &tmp_pbo); 
     
    8241025 
    8251026    Flush(true); 
    8261027 
    827     MakeCurrent(false); 
    828  
    829     if (tmp_pbo) 
    830         m_priv->m_pbos.push_back(tmp_pbo); 
    831  
    8321028    return tmp_pbo; 
    8331029} 
    8341030 
    835 void OpenGLContext::DeletePBO(uint pbo) 
    836 { 
    837     MakeCurrent(true); 
    838  
    839     vector<GLuint>::iterator it; 
    840     for (it = m_priv->m_pbos.begin(); 
    841          it != m_priv->m_pbos.end(); it++) 
    842     { 
    843         if (*(it) == pbo) 
    844         { 
    845             GLuint glpbo = pbo; 
    846             gMythGLDeleteBuffersARB(1, &glpbo); 
    847             m_priv->m_pbos.erase(it); 
    848             break; 
    849         } 
    850     } 
    851  
    852     Flush(true); 
    853  
    854     MakeCurrent(false); 
    855 } 
    856  
    857 void OpenGLContext::DeletePBOs(void) 
    858 { 
    859     vector<GLuint>::iterator it; 
    860     for (it = m_priv->m_pbos.begin(); 
    861          it != m_priv->m_pbos.end(); it++) 
    862     { 
    863         gMythGLDeleteBuffersARB(1, &(*(it))); 
    864     } 
    865     m_priv->m_pbos.clear(); 
    866  
    867     Flush(true); 
    868 } 
    869  
    8701031int OpenGLContext::SetPictureAttribute( 
    8711032    PictureAttribute attribute, int newValue) 
    8721033{ 
  • libs/libmythtv/openglcontext.h

    diff -ur -X excl mythtv-vid-17/libs/libmythtv/openglcontext.h mythtv-vid-18/libs/libmythtv/openglcontext.h
    old new  
    1414#include "frame.h" 
    1515#include "videooutbase.h" 
    1616 
     17#ifndef GL_BGRA 
     18#define GL_BGRA                           0x80E1 
     19#endif 
     20#ifndef GL_UNSIGNED_BYTE 
     21#define GL_UNSIGNED_BYTE                  0x1401 
     22#endif 
     23#ifndef GL_RGBA8 
     24#define GL_RGBA8                          0x8058 
     25#endif 
     26#ifndef GL_LINEAR 
     27#define GL_LINEAR                         0x2601 
     28#endif 
     29#ifndef GL_CLAMP_TO_EDGE 
     30#define GL_CLAMP_TO_EDGE                  0x812F 
     31#endif 
     32 
    1733class OpenGLVideo; 
    1834class PrivateContext; 
    1935 
     
    5773    void SwapBuffers(void); 
    5874    void Flush(bool use_fence); 
    5975 
    60     uint GetMaxTexSize(void) const { return m_max_tex_size; } 
    6176    uint GetScreenNum(void)  const { return m_screen_num;   } 
    6277 
    63     uint CreateTexture(void); 
    64     bool SetupTexture(const QSize &size, uint tex, int filt); 
    65     void SetupTextureFilters(uint tex, int filt); 
     78    void UpdateTexture(uint tex, const unsigned char *buf, 
     79                       const int *offsets, 
     80                       const int *pitches, 
     81                       VideoFrameType fmt, 
     82                       bool interlaced = FALSE, 
     83                       const unsigned char* alpha = NULL); 
     84    uint CreateTexture(QSize tot_size, QSize vid_size, 
     85                       bool use_pbo, uint type, 
     86                       uint data_type = GL_UNSIGNED_BYTE, 
     87                       uint data_fmt = GL_BGRA, 
     88                       uint internal_fmt = GL_RGBA8, 
     89                       uint filter = GL_LINEAR, 
     90                       uint wrap = GL_CLAMP_TO_EDGE); 
     91    void SetTextureFilters(uint tex, uint filt, uint wrap); 
    6692    void DeleteTexture(uint tex); 
    67     int  GetTextureType(void) const; 
    68     void EnableTextures(void); 
     93    void GetTextureType(uint &current, bool &rect); 
     94    void EnableTextures(uint type, uint tex_type = 0); 
    6995 
    7096    bool CreateFragmentProgram(const QString &program, uint &prog); 
    7197    void DeleteFragmentProgram(uint prog); 
    7298    void BindFragmentProgram(uint fp); 
    7399    void InitFragmentParams(uint fp, float a, float b, float c, float d); 
    74100 
    75     bool CreateFrameBuffer(uint &fb, uint tex, const QSize &size); 
     101    bool CreateFrameBuffer(uint &fb, uint tex); 
    76102    void DeleteFrameBuffer(uint fb); 
    77103    void BindFramebuffer(uint fb); 
    78104 
     
    81107 
    82108    static bool IsGLXSupported(Display *display, uint major, uint minor); 
    83109 
    84     uint CreatePBO(QSize size); 
    85     void DeletePBO(uint pbo); 
    86     void UpdatePBO(uint tex, uint pbo, 
    87                    const VideoFrame *frame, 
    88                    const unsigned char *alpha = NULL); 
    89110    int SetPictureAttribute(PictureAttribute attributeType, int newValue); 
    90111    PictureAttributeSupported GetSupportedPictureAttributes(void) const; 
    91112    void SetColourParams(void); 
     
    98119            ((m_major_ver == major) && (m_minor_ver >= minor)); 
    99120    } 
    100121 
     122    uint CreatePBO(uint tex); 
     123 
    101124    void DeleteTextures(void); 
    102125    void DeletePrograms(void); 
    103126    void DeleteFrameBuffers(void); 
    104     void DeletePBOs(void); 
     127    uint GetBufferSize(QSize size, uint fmt, uint type); 
     128    bool ClearTexture(uint tex); 
    105129 
    106130    PrivateContext *m_priv; 
    107131 
     
    138162    void SwapBuffers(void) { } 
    139163    void Flush(bool) { } 
    140164 
    141     uint GetMaxTexSize(void) const { return 0; } 
    142165    uint GetScreenNum(void)  const { return 0; } 
    143166 
    144     uint CreateTexture(void) { return 0; } 
    145     bool SetupTexture(const QSize&, uint, int) { return false; } 
    146     void SetupTextureFilters(uint, int) { } 
     167    void UpdateTexture(uint, const unsigned char*, 
     168                       const int *, const int *, 
     169                       VideoFrameType, bool = FALSE, 
     170                       const unsigned char* = NULL) { } 
     171    uint CreateTexture(QSize, QSize, bool, uint, 
     172                       uint = 0, uint = 0, uint = 0, 
     173                       uint = 0, uint = 0) { return 0; } 
     174    void SetTextureFilters(uint, uint, uint) { } 
    147175    void DeleteTexture(uint) { } 
    148     int  GetTextureType(void) const { return 0; } 
    149     void EnableTextures(void) { } 
     176    void GetTextureType(uint&, bool&) { } 
     177    void EnableTextures(uint, uint = 0) { } 
    150178 
    151179    bool CreateFragmentProgram(const QString&, uint&) { return false; } 
    152180    void DeleteFragmentProgram(uint) { } 
    153181    void BindFragmentProgram(uint) { } 
    154182    void InitFragmentParams(uint, float, float, float, float) { } 
    155183 
    156     bool CreateFrameBuffer(uint&, uint, const QSize&) { return false; } 
     184    bool CreateFrameBuffer(uint&, uint) { return false; } 
    157185    void DeleteFrameBuffer(uint); 
    158186    void BindFramebuffer(uint); 
    159187 
    160188    bool IsFeatureSupported(GLFeatures) const { return false; } 
    161189    static bool IsGLXSupported(Display*, uint, uint) { return false; } 
    162190 
    163     uint CreatePBO(QSize); 
    164     void DeletePBO(uint); 
    165     void UpdatePBO(uint, uint, const VideoFrame*, const unsigned char*); 
    166191    int SetPictureAttribute(PictureAttribute, int) { return -1; } 
    167192    PictureAttributeSupported GetSupportedPictureAttributes(void) const 
    168193        { return kPictureAttributeSupported_None; } 
  • libs/libmythtv/openglvideo.cpp

    diff -ur -X excl mythtv-vid-17/libs/libmythtv/openglvideo.cpp mythtv-vid-18/libs/libmythtv/openglvideo.cpp
    old new  
    4343    hardwareDeinterlacing(false), 
    4444    useColourControl(false),  viewportControl(false), 
    4545    inputTextureSize(0,0),    currentFrameNum(0), 
    46     inputUpdated(false), 
    47     fastTexStreaming(false),  pixelBufferObject(0), 
     46    inputUpdated(false),       
     47    textureRects(false),      textureType(GL_TEXTURE_2D), 
    4848    convertSize(0,0),         convertBuf(NULL), 
    4949 
    5050    videoResize(false),       videoResizeRect(0,0,0,0), 
     
    6363{ 
    6464    ShutDownYUV2RGB(); 
    6565 
    66     if (pixelBufferObject) 
    67         gl_context->DeletePBO(pixelBufferObject); 
    68     pixelBufferObject = 0; 
    69  
    7066    for (uint i = 0; i < inputTextures.size(); i++) 
    7167        gl_context->DeleteTexture(inputTextures[i]); 
    7268    inputTextures.clear(); 
     
    10399    display_video_rect    = displayVideoRect; 
    104100    video_rect            = videoRect; 
    105101    masterViewportSize    = QSize(1920, 1080); 
    106  
    107     QSize rect            = GetTextureSize(video_dim); 
    108  
    109     frameBufferRect       = QRect(QPoint(0,0), rect); 
     102    frameBufferRect       = QRect(QPoint(0,0), video_dim); 
    110103    softwareDeinterlacer  = ""; 
    111104    hardwareDeinterlacing = false; 
    112105    useColourControl      = colour_control; 
     
    119112    inputUpdated          = false; 
    120113    gl_letterbox_colour   = letterbox_colour; 
    121114 
     115    gl_context->GetTextureType(textureType, textureRects); 
     116 
    122117    SetViewPort(display_visible_rect.size()); 
    123118 
    124     fastTexStreaming = gl_context->IsFeatureSupported(kGLExtPBufObj); 
     119    bool use_pbo = gl_context->IsFeatureSupported(kGLExtPBufObj); 
    125120 
    126121    if (osd) 
    127122    { 
    128123        QSize osdsize = display_visible_rect.size(); 
    129         if (fastTexStreaming) 
    130         { 
    131             GLuint tex = CreateVideoTexture(osdsize, inputTextureSize); 
    132             pixelBufferObject = gl_context->CreatePBO(osdsize); 
     124        GLuint tex = CreateVideoTexture(osdsize, inputTextureSize, use_pbo); 
    133125 
    134             if (tex && pixelBufferObject && 
    135                 AddFilter(kGLFilterYUV2RGBA) && 
    136                 AddFilter(kGLFilterResize)) 
    137             { 
    138                 inputTextures.push_back(tex); 
    139             } 
    140             else 
    141             { 
    142                 Teardown(); 
    143                 fastTexStreaming = false; 
    144             } 
     126        if (tex && 
     127            AddFilter(kGLFilterYUV2RGBA) && 
     128            AddFilter(kGLFilterResize)) 
     129        { 
     130            inputTextures.push_back(tex); 
    145131        } 
    146          
    147         if (!fastTexStreaming) 
    148         {    
    149             QSize half_size(osdsize.width() >> 1, osdsize.height() >>1); 
    150             GLuint alphatex = CreateVideoTexture(osdsize, inputTextureSize); 
    151             GLuint utex = CreateVideoTexture(half_size, inputTextureSize); 
    152             GLuint vtex = CreateVideoTexture(half_size, inputTextureSize); 
    153             GLuint ytex = CreateVideoTexture(osdsize, inputTextureSize); 
    154  
    155             if ((alphatex && ytex && utex && vtex) && 
    156                  AddFilter(kGLFilterYUV2RGBA) && 
    157                  AddFilter(kGLFilterResize)) 
    158             { 
    159                 inputTextures.push_back(ytex); 
    160                 inputTextures.push_back(utex); 
    161                 inputTextures.push_back(vtex); 
    162                 inputTextures.push_back(alphatex); 
    163             } 
    164             else 
    165             { 
    166                 Teardown(); 
    167             } 
     132        else 
     133        { 
     134            Teardown(); 
    168135        } 
    169136    } 
    170137    else 
    171138    { 
    172         if (fastTexStreaming) 
     139        GLuint tex = CreateVideoTexture(actual_video_dim, 
     140                                        inputTextureSize, use_pbo); 
     141 
     142        if (tex && AddFilter(kGLFilterYUV2RGB)) 
    173143        { 
    174             GLuint tex = CreateVideoTexture(actual_video_dim, inputTextureSize); 
    175             pixelBufferObject = gl_context->CreatePBO(actual_video_dim); 
    176   
    177             if (tex && pixelBufferObject && 
    178                 AddFilter(kGLFilterYUV2RGB)) 
    179             { 
    180                 inputTextures.push_back(tex); 
    181             } 
    182             else 
    183             { 
    184                 Teardown(); 
    185                 fastTexStreaming = false; 
    186             } 
     144            inputTextures.push_back(tex); 
    187145        } 
    188  
    189         if (!fastTexStreaming) 
     146        else 
    190147        { 
    191             QSize half_size(actual_video_dim.width() >> 1, actual_video_dim.height() >>1); 
    192             GLuint utex = CreateVideoTexture(half_size, inputTextureSize); 
    193             GLuint vtex = CreateVideoTexture(half_size, inputTextureSize); 
    194             GLuint ytex = CreateVideoTexture(actual_video_dim, inputTextureSize); 
    195  
    196             if ((ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGB)) 
    197             { 
    198                 inputTextures.push_back(ytex); 
    199                 inputTextures.push_back(utex); 
    200                 inputTextures.push_back(vtex); 
    201             } 
    202             else 
    203             { 
    204                 Teardown(); 
    205             } 
     148            Teardown(); 
    206149        } 
    207150    } 
    208151 
     
    219162                "Falling back to software conversion.\n\t\t\t" 
    220163                "Any opengl filters will also be disabled."); 
    221164 
    222         GLuint rgb24tex = CreateVideoTexture(actual_video_dim, 
    223                                              inputTextureSize); 
     165        GLuint bgra32tex = CreateVideoTexture(actual_video_dim, 
     166                                             inputTextureSize, use_pbo); 
    224167 
    225         if (rgb24tex && AddFilter(kGLFilterResize)) 
     168        if (bgra32tex && AddFilter(kGLFilterResize)) 
    226169        { 
    227             inputTextures.push_back(rgb24tex); 
     170            inputTextures.push_back(bgra32tex); 
    228171        } 
    229172        else 
    230173        { 
     
    234177        } 
    235178    } 
    236179 
    237     if (fastTexStreaming) 
    238         VERBOSE(VB_PLAYBACK, LOC + "Using PBO accelerated texture uploading."); 
     180#ifdef MMX 
     181    bool mmx = true; 
     182#else 
     183    bool mmx = false; 
     184#endif 
     185 
     186    VERBOSE(VB_PLAYBACK, LOC +  
     187            QString("Using packed textures with%1 mmx and with%2 PBOs") 
     188            .arg(mmx ? "" : "out").arg(use_pbo ? "" : "out")); 
    239189 
    240190    return true; 
    241191} 
     
    298248                QSize fb_size = GetTextureSize(video_dim); 
    299249                for (int i = 0; i < buffers_diff; i++) 
    300250                { 
    301                     if (!AddFrameBuffer(tmp_buf, tmp_tex, fb_size)) 
     251                    if (!AddFrameBuffer(tmp_buf, fb_size, tmp_tex, video_dim)) 
    302252                        return false; 
    303253                    else 
    304254                    { 
     
    359309 
    360310    if (filters.size() == 1) 
    361311    { 
    362         SetTextureFilters(&inputTextures, GL_LINEAR); 
     312        SetTextureFilters(&inputTextures, GL_LINEAR, GL_CLAMP_TO_EDGE); 
    363313        return; 
    364314    } 
    365315 
    366     SetTextureFilters(&inputTextures, GL_NEAREST); 
     316    SetTextureFilters(&inputTextures, GL_NEAREST, GL_CLAMP_TO_EDGE); 
    367317    vector<GLuint> textures; 
    368318    glfilt_map_t::iterator it; 
    369319    for (it = filters.begin(); it != filters.end(); it++) 
    370         SetTextureFilters(&(it->second->frameBufferTextures), GL_NEAREST); 
     320        SetTextureFilters(&(it->second->frameBufferTextures), 
     321                          GL_NEAREST, GL_CLAMP_TO_EDGE); 
    371322 
    372323    // resize or last active (ie don't need resize) need GL_LINEAR 
    373324    glfilt_map_t::reverse_iterator rit; 
     
    377328    { 
    378329        if (next && (rit->second->outputBuffer != kNoBuffer)) 
    379330        { 
    380             SetTextureFilters(&(rit->second->frameBufferTextures), GL_LINEAR); 
     331            SetTextureFilters(&(rit->second->frameBufferTextures), 
     332                              GL_LINEAR, GL_CLAMP_TO_EDGE); 
    381333            return; 
    382334        } 
    383335 
     
    388340        } 
    389341    } 
    390342 
    391     SetTextureFilters(&inputTextures, GL_LINEAR); 
     343    SetTextureFilters(&inputTextures, GL_LINEAR, GL_CLAMP_TO_EDGE); 
    392344} 
    393345 
    394346// locking ok 
     
    410362    { 
    411363        temp->numInputs = 2; 
    412364    } 
    413     else if ((filter == kGLFilterYUV2RGB && !fastTexStreaming) || 
    414              (filter == kGLFilterOneFieldDeintDFR) || 
     365    else if ((filter == kGLFilterOneFieldDeintDFR) || 
    415366             (filter == kGLFilterKernelDeintDFR) || 
    416367             (filter == kGLFilterLinearBlendDeintDFR)) 
    417368    { 
    418369        temp->numInputs = 3; 
    419370    } 
    420     else if ((filter == kGLFilterYUV2RGBA) && !fastTexStreaming) 
    421     { 
    422         temp->numInputs = 4; 
    423     } 
    424371 
    425372    GLuint program = 0; 
    426373    if (filter != kGLFilterNone && filter != kGLFilterResize) 
     
    500447    } 
    501448 
    502449    QString program = GetProgramString(name); 
    503     QString texType = (gl_context->IsFeatureSupported(kGLExtRect)) ? "RECT" : "2D"; 
     450    QString texType = (textureRects) ? "RECT" : "2D"; 
    504451    program.replace("%1", texType); 
    505452 
    506453    uint ret; 
     
    516463} 
    517464 
    518465// locking ok 
    519 bool OpenGLVideo::AddFrameBuffer(uint &framebuffer, 
    520                                  uint &texture, QSize size) 
     466bool OpenGLVideo::AddFrameBuffer(uint &framebuffer, QSize fb_size, 
     467                                 uint &texture, QSize vid_size) 
    521468{ 
    522469    if (!gl_context->IsFeatureSupported(kGLExtFBufObj)) 
    523470    { 
     
    525472        return false; 
    526473    } 
    527474 
    528     texture = gl_context->CreateTexture(); 
     475    texture = gl_context->CreateTexture(fb_size, vid_size, false, textureType); 
    529476 
    530     bool ok = gl_context->CreateFrameBuffer(framebuffer, texture, size); 
     477    bool ok = gl_context->CreateFrameBuffer(framebuffer, texture); 
    531478 
    532479    if (!ok) 
    533480        gl_context->DeleteTexture(texture); 
     
    552499} 
    553500 
    554501// locking ok 
    555 uint OpenGLVideo::CreateVideoTexture(QSize size, QSize &tex_size) 
     502uint OpenGLVideo::CreateVideoTexture(QSize size, QSize &tex_size, 
     503                                     bool use_pbo) 
    556504{ 
    557     uint tmp_tex = gl_context->CreateTexture(); 
    558  
    559505    QSize temp = GetTextureSize(size); 
     506    uint tmp_tex = gl_context->CreateTexture(temp, size, use_pbo, 
     507                                             textureType); 
    560508 
    561     if ((temp.width()  > (int)gl_context->GetMaxTexSize()) || 
    562         (temp.height() > (int)gl_context->GetMaxTexSize()) || 
    563         !gl_context->SetupTexture(temp, tmp_tex, GL_LINEAR)) 
     509    if (!tmp_tex) 
    564510    { 
    565511        VERBOSE(VB_PLAYBACK, LOC_ERR + "Could not create texture."); 
    566         gl_context->DeleteTexture(tmp_tex); 
    567512        return 0; 
    568513    } 
    569514 
    570515    tex_size = temp; 
    571516 
    572     VERBOSE(VB_PLAYBACK, LOC + QString("Created main input texture %1x%2") 
     517    VERBOSE(VB_PLAYBACK, LOC + QString("Created texture (%1x%2)") 
    573518            .arg(temp.width()).arg(temp.height())); 
    574519 
    575520    return tmp_tex; 
     
    578523// locking ok 
    579524QSize OpenGLVideo::GetTextureSize(const QSize &size) 
    580525{ 
    581     if (gl_context->IsFeatureSupported(kGLExtRect)) 
     526    if (textureRects) 
    582527        return size; 
    583528 
    584529    int w = 64; 
     
    613558 
    614559    if (filters.count(kGLFilterYUV2RGB) && (frame->codec == FMT_YV12)) 
    615560    { 
    616         if (fastTexStreaming && pixelBufferObject) 
    617         { 
    618             gl_context->UpdatePBO(inputTextures[0], pixelBufferObject, 
    619                                   frame); 
    620             inputUpdated = true; 
    621             return; 
    622         } 
    623  
    624         UpdateInput(frame->buf, frame->offsets, FMT_YV12, actual_video_dim); 
     561        gl_context->UpdateTexture(inputTextures[0], frame->buf, 
     562                                  frame->offsets, frame->pitches, FMT_YV12, 
     563                                  frame->interlaced_frame); 
     564        inputUpdated = true; 
    625565        return; 
    626566    } 
    627567 
     
    634574 
    635575        convertSize = actual_video_dim; 
    636576        convertBuf = new unsigned char[ 
    637             (actual_video_dim.width() * actual_video_dim.height() * 3) + 128]; 
     577            (actual_video_dim.width() * actual_video_dim.height() * 4) + 128]; 
    638578    } 
    639579 
    640580    if (convertBuf) 
    641581    { 
    642582        AVPicture img_in, img_out; 
    643583 
    644         avpicture_fill(&img_out, (uint8_t *)convertBuf, PIX_FMT_RGB24, 
     584        avpicture_fill(&img_out, (uint8_t *)convertBuf, PIX_FMT_BGRA, 
    645585                       convertSize.width(), convertSize.height()); 
    646586        avpicture_fill(&img_in, (uint8_t *)frame->buf, PIX_FMT_YUV420P, 
    647587                       convertSize.width(), convertSize.height()); 
    648         img_convert(&img_out, PIX_FMT_RGB24, 
     588        img_convert(&img_out, PIX_FMT_BGRA, 
    649589                    &img_in,  PIX_FMT_YUV420P, 
    650590                    convertSize.width(), convertSize.height()); 
    651591 
    652592        int offset = 0; 
    653         UpdateInput(convertBuf, &offset, FMT_RGB24, convertSize); 
     593        gl_context->UpdateTexture(inputTextures[0], convertBuf, 
     594                                  &offset, &offset, FMT_BGRA); 
    654595    } 
     596 
     597    inputUpdated = true; 
    655598} 
    656599 
    657600// locking ok 
     
    661604{ 
    662605    OpenGLContextLocker ctx_lock(gl_context); 
    663606 
    664     inputUpdated = false; 
    665  
    666     if (fastTexStreaming && pixelBufferObject && 
    667         FMT_YV12 == format && alpha) 
    668     { 
    669         VideoFrame frame; 
    670         frame.interlaced_frame = false; 
    671         frame.codec = FMT_YV12; 
    672         frame.buf = (unsigned char *)buf; 
    673         frame.width = size.width(); 
    674         frame.height = size.height(); 
    675         frame.offsets[0] = offsets[0]; 
    676         frame.offsets[1] = offsets[1]; 
    677         frame.offsets[2] = offsets[2]; 
    678         frame.pitches[0] = size.width(); 
    679         frame.pitches[1] = size.width() >> 1; 
    680         frame.pitches[2] = size.width() >> 1; 
    681         gl_context->UpdatePBO(inputTextures[0], pixelBufferObject, 
    682                               &frame, alpha); 
    683  
    684         inputUpdated = true; 
     607    if (size.width()  != actual_video_dim.width()  || 
     608        size.height() != actual_video_dim.height() || 
     609        format != FMT_YV12 || !alpha) 
    685610        return; 
    686     } 
    687611 
    688     copy_pixels_to_texture( 
    689         buf + offsets[0], format, size, 
    690         inputTextures[0], gl_context->GetTextureType()); 
    691  
    692     if (FMT_YV12 == format) 
    693     { 
    694         QSize chroma_size(size.width() >> 1, size.height() >> 1); 
    695         copy_pixels_to_texture( 
    696             buf + offsets[1], format, chroma_size, 
    697             inputTextures[1], 
    698             gl_context->GetTextureType()); 
    699         copy_pixels_to_texture( 
    700             buf + offsets[2], format, chroma_size, 
    701             inputTextures[2], 
    702             gl_context->GetTextureType()); 
    703         if (alpha) 
    704         { 
    705             copy_pixels_to_texture( 
    706                 alpha, FMT_ALPHA, size, 
    707                 inputTextures[3], 
    708                 gl_context->GetTextureType()); 
    709         } 
    710     } 
     612    int pitches[3] = {size.width(), size.width() >> 1, size.width() >> 1}; 
     613 
     614    gl_context->UpdateTexture(inputTextures[0], buf, 
     615                              offsets, pitches, FMT_YV12, 
     616                              false, alpha); 
    711617 
    712618    inputUpdated = true; 
    713619} 
     
    828734 
    829735    OpenGLContextLocker ctx_lock(gl_context); 
    830736 
     737    // enable correct texture type 
     738    gl_context->EnableTextures(inputTextures[0]); 
     739 
    831740    vector<GLuint> inputs = inputTextures; 
    832741    QSize inputsize = inputTextureSize; 
     742    QSize realsize  = GetTextureSize(video_dim); 
    833743 
    834744    glfilt_map_t::iterator it; 
    835745    for (it = filters.begin(); it != filters.end(); it++) 
     
    852762        if (!inputUpdated && type == kGLFilterYUV2RGBA) 
    853763        { 
    854764            inputs = filter->frameBufferTextures; 
    855             inputsize = video_dim; 
     765            inputsize = realsize; 
    856766            continue; 
    857767        } 
    858768 
     
    862772            (!(softwareDeinterlacing && softwareDeinterlacer == "bobdeint"))) 
    863773        { 
    864774            inputs = filter->frameBufferTextures; 
    865             inputsize = video_dim; 
     775            inputsize = realsize; 
    866776            continue; 
    867777        } 
    868778 
     
    882792            t_bottom = (float)video_rect.height() + t_top; 
    883793        } 
    884794 
    885         if (!gl_context->IsFeatureSupported(kGLExtRect) && 
     795        if (!textureRects && 
    886796            (inputsize.width() > 0) && (inputsize.height() > 0)) 
    887797        { 
    888798            t_right  /= inputsize.width(); 
     
    930840            } 
    931841        } 
    932842 
    933         float t_right_uv = t_right; 
    934         float t_top_uv   = t_top; 
    935         float t_bottom_uv = t_bottom; 
    936         float t_left_uv  = t_left; 
    937  
    938         if (gl_context->IsFeatureSupported(kGLExtRect)) 
    939         { 
    940             t_right_uv  /= 2; 
    941             t_top_uv    /= 2; 
    942             t_bottom_uv /= 2; 
    943             t_left_uv   /= 2; 
    944         } 
    945  
    946843        // vertex coordinates 
    947844        QRect display = (filter->frameBuffers.empty() ||   
    948845                         filter->outputBuffer == kDefaultBuffer) ?  
     
    1013910        for (uint i = 0; i < inputs.size(); i++) 
    1014911        { 
    1015912            glActiveTexture(GL_TEXTURE0 + i); 
    1016             glBindTexture(gl_context->GetTextureType(), inputs[i]); 
     913            glBindTexture(textureType, inputs[i]); 
    1017914        } 
    1018915 
    1019916        // enable fragment program and set any environment variables 
     
    1057954            glEnable(GL_BLEND); 
    1058955 
    1059956        // draw quad 
    1060  
    1061         bool multi = ((type == kGLFilterYUV2RGB || 
    1062                         type == kGLFilterYUV2RGBA) && 
    1063                         !fastTexStreaming); 
    1064         bool multi_alpha = multi && (type == kGLFilterYUV2RGBA); 
    1065  
    1066957        glBegin(GL_QUADS); 
    1067958        glTexCoord2f(t_left, t_top); 
    1068         if (multi) 
    1069         { 
    1070             glMultiTexCoord2f(GL_TEXTURE1, t_left_uv, t_top_uv); 
    1071             glMultiTexCoord2f(GL_TEXTURE2, t_left_uv, t_top_uv); 
    1072             if (multi_alpha) 
    1073                 glMultiTexCoord2f(GL_TEXTURE3, t_left_uv, t_top_uv); 
    1074         } 
    1075959        glVertex2f(vleft,  vtop); 
    1076960 
    1077961        glTexCoord2f(t_right, t_top); 
    1078         if (multi) 
    1079         { 
    1080             glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_top_uv); 
    1081             glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_top_uv); 
    1082             if (multi_alpha) 
    1083                 glMultiTexCoord2f(GL_TEXTURE3, t_right, t_top); 
    1084         } 
    1085962        glVertex2f(vright, vtop); 
    1086963 
    1087964        glTexCoord2f(t_right, t_bottom); 
    1088         if (multi) 
    1089         { 
    1090             glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_bottom_uv); 
    1091             glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_bottom_uv); 
    1092             if (multi_alpha) 
    1093                 glMultiTexCoord2f(GL_TEXTURE3, t_right, t_bottom); 
    1094         } 
    1095965        glVertex2f(vright, vbot); 
    1096966 
    1097967        glTexCoord2f(t_left, t_bottom); 
    1098         if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA) 
    1099         { 
    1100             glMultiTexCoord2f(GL_TEXTURE1, t_left_uv, t_bottom_uv); 
    1101             glMultiTexCoord2f(GL_TEXTURE2, t_left_uv, t_bottom_uv); 
    1102             if (type == kGLFilterYUV2RGBA) 
    1103                 glMultiTexCoord2f(GL_TEXTURE3, t_left_uv, t_bottom); 
    1104         } 
    1105968        glVertex2f(vleft,  vbot); 
    1106969        glEnd(); 
    1107970 
     
    11401003            gl_context->BindFramebuffer(0); 
    11411004 
    11421005        inputs = filter->frameBufferTextures; 
    1143         inputsize = video_dim; 
     1006        inputsize = realsize; 
    11441007    } 
    11451008 
    11461009    currentFrameNum = frame; 
     
    11601023} 
    11611024 
    11621025// locking ok 
    1163 void OpenGLVideo::SetTextureFilters(vector<GLuint> *textures, int filt) 
     1026void OpenGLVideo::SetTextureFilters(vector<GLuint> *textures, 
     1027                                    int filt, int wrap) 
    11641028{ 
    11651029    if (textures->empty()) 
    11661030        return; 
    11671031 
    11681032    for (uint i = 0; i < textures->size(); i++) 
    1169         gl_context->SetupTextureFilters((*textures)[i], filt); 
     1033        gl_context->SetTextureFilters((*textures)[i], filt, wrap); 
    11701034} 
    11711035 
    11721036// locking ok 
     
    12341098    return ""; 
    12351099} 
    12361100 
    1237 static const QString init_norm = 
    1238 "ATTRIB ytex  = fragment.texcoord[0];" 
    1239 "ATTRIB uvtex = fragment.texcoord[1];" 
    1240 "TEMP res, tmp;"; 
    1241  
    1242 static const QString init_alpha = 
    1243 "TEMP alpha;" 
    1244 "TEX alpha, ytex, texture[3], %1;"; 
    1245  
    1246 static const QString tex_sample = 
    1247 "TEX res,   ytex,  texture[0], %1;" 
    1248 "TEX tmp.x, uvtex, texture[1], %1;" 
    1249 "TEX tmp.y, uvtex, texture[2], %1;"; 
    1250  
    1251 static const QString colour_control = 
    1252 "PARAM  adj  = program.env[0];" 
    1253 "SUB res, res, 0.5;" 
    1254 "MAD res, res, adj.yyyy, adj.xxxx;" 
    1255 "SUB tmp, tmp, { 0.5, 0.5 };" 
    1256 "MAD tmp, adj.zzzz, tmp, 0.5;"; 
    1257  
    12581101static const QString colour_control_fast = 
    12591102"PARAM  adj  = program.env[0];" 
    12601103"SUB res, res, 0.5;" 
    12611104"MAD res, res, adj.zzzy, adj.wwwx;"; 
    12621105 
    1263 static const QString end_norm = 
    1264 "MAD res, res, 1.164, -0.063;" 
    1265 "SUB tmp, tmp, { 0.5, 0.5 };" 
    1266 "MAD res, { 0, -.392, 2.017 }, tmp.xxxw, res;" 
    1267 "MAD result.color, { 1.596, -.813, 0, 0 }, tmp.yyyw, res;"; 
    1268  
    1269 static const QString end_alpha = 
    1270 "MOV result.color.a, alpha.a;"; 
    1271  
    12721106static const QString init_fast =  
    12731107"ATTRIB tex  = fragment.texcoord[0];" 
    12741108"TEMP tmp, res;" 
     
    12991133    switch (name) 
    13001134    { 
    13011135        case kGLFilterYUV2RGB: 
    1302             if (fastTexStreaming) 
    1303             { 
    1304                 ret += init_fast; 
    1305                 if (useColourControl) 
    1306                     ret += colour_control_fast; 
    1307                 ret += end_fast; 
    1308             } 
    1309             else 
    1310             { 
    1311                 ret = ret + init_norm + tex_sample; 
    1312                 if (useColourControl) 
    1313                     ret += colour_control; 
    1314                 ret += end_norm; 
    1315             } 
     1136            ret += init_fast; 
     1137            if (useColourControl) 
     1138                ret += colour_control_fast; 
     1139            ret += end_fast; 
    13161140            break; 
    13171141 
    13181142        case kGLFilterYUV2RGBA: 
    1319             if (fastTexStreaming) 
    1320             { 
    1321                 ret += init_fast + init_fast_alpha; 
    1322                 if (useColourControl) 
    1323                     ret += colour_control_fast; 
    1324                 ret += end_fast_alpha; 
    1325             } 
    1326             else 
    1327             { 
    1328                 ret = ret + init_norm + init_alpha + tex_sample; 
    1329                 if (useColourControl) 
    1330                     ret += colour_control; 
    1331                 ret = ret + end_norm + end_alpha; 
    1332             } 
     1143            ret += init_fast + init_fast_alpha; 
     1144            if (useColourControl) 
     1145                ret += colour_control_fast; 
     1146            ret += end_fast_alpha; 
    13331147            break; 
    13341148 
    13351149        case kGLFilterKernelDeint: 
  • libs/libmythtv/openglvideo.h

    diff -ur -X excl mythtv-vid-17/libs/libmythtv/openglvideo.h mythtv-vid-18/libs/libmythtv/openglvideo.h
    old new  
    6464    void UpdateInputFrame(const VideoFrame *frame); 
    6565    void UpdateInput(const unsigned char *buf, const int *offsets, 
    6666                     int format, QSize size, 
    67                      const unsigned char *alpha = NULL); 
     67                     const unsigned char *alpha); 
    6868 
    6969    bool AddFilter(const QString &filter) 
    7070         { return AddFilter(StringToFilter(filter)); } 
     
    9696    bool RemoveFilter(OpenGLFilterType filter); 
    9797    bool OptimiseFilters(void); 
    9898    OpenGLFilterType GetDeintFilter(void) const; 
    99     bool AddFrameBuffer(uint &framebuffer, uint &texture, QSize size); 
     99    bool AddFrameBuffer(uint &framebuffer, QSize fb_size, 
     100                        uint &texture, QSize vid_size); 
    100101    uint AddFragmentProgram(OpenGLFilterType name); 
    101     uint CreateVideoTexture(QSize size, QSize &tex_size); 
     102    uint CreateVideoTexture(QSize size, QSize &tex_size, 
     103                            bool use_pbo = false); 
    102104    QString GetProgramString(OpenGLFilterType filter); 
    103105    void CalculateResize(float &left,  float &top, 
    104106                         float &right, float &bottom); 
     
    109111    void SetFiltering(void); 
    110112 
    111113    void Rotate(vector<uint> *target); 
    112     void SetTextureFilters(vector<uint> *textures, int filt); 
     114    void SetTextureFilters(vector<uint> *textures, int filt, int wrap); 
    113115 
    114116    OpenGLContext *gl_context; 
    115117    QSize          video_dim; 
     
    129131    glfilt_map_t   filters; 
    130132    long long      currentFrameNum; 
    131133    bool           inputUpdated; 
    132     bool           fastTexStreaming; 
    133     uint           pixelBufferObject; 
     134    bool           textureRects; 
     135    uint           textureType; 
    134136 
    135137    QSize            convertSize; 
    136138    unsigned char   *convertBuf; 
     
    155157                { (void) osd; return false; } 
    156158 
    157159    void UpdateInputFrame(const VideoFrame*) { } 
    158     void UpdateInput(const unsigned char*, const int*, int, QSize, unsigned char* = NULL) { } 
     160    void UpdateInput(const unsigned char*, const int*, 
     161                     int, QSize, unsigned char* = NULL) { } 
    159162 
    160163    bool AddFilter(const QString&) { return false; } 
    161164    bool RemoveFilter(const QString&) { return false; } 
  • libs/libmythtv/util-opengl.cpp

    diff -ur -X excl mythtv-vid-17/libs/libmythtv/util-opengl.cpp mythtv-vid-18/libs/libmythtv/util-opengl.cpp
    old new  
    306306    return glx_window; 
    307307}                        
    308308 
    309 void copy_pixels_to_texture(const unsigned char *buf, 
    310                             int                  buffer_format, 
    311                             const QSize         &buffer_size, 
    312                             int                  texture, 
    313                             int                  texture_type) 
    314 { 
    315     glBindTexture(texture_type, texture); 
    316  
    317     uint format; 
    318     switch (buffer_format) 
    319     { 
    320         case FMT_YV12: 
    321             format = GL_LUMINANCE; 
    322             break; 
    323         case FMT_RGB24: 
    324             format = GL_RGB; 
    325             break; 
    326         case FMT_RGBA32: 
    327             format = GL_RGBA; 
    328             break; 
    329         case FMT_ALPHA: 
    330             format = GL_ALPHA; 
    331             break; 
    332         default: 
    333             return; 
    334     } 
    335  
    336     glTexSubImage2D( 
    337         texture_type, 
    338         0, 0, 0, 
    339         buffer_size.width(), buffer_size.height(), 
    340         format, GL_UNSIGNED_BYTE, 
    341         buf); 
    342 } 
    343  
    344309__GLXextFuncPtr get_gl_proc_address(const QString &procName) 
    345310{ 
    346311    __GLXextFuncPtr ret = NULL; 
  • libs/libmythtv/util-opengl.h

    diff -ur -X excl mythtv-vid-17/libs/libmythtv/util-opengl.h mythtv-vid-18/libs/libmythtv/util-opengl.h
    old new  
    115115                         GLXPbuffer   glx_pbuffer, 
    116116                         const QSize &window_size); 
    117117 
    118 void copy_pixels_to_texture(const unsigned char *buf, 
    119                             int          buffer_format, 
    120                             const QSize &buffer_size, 
    121                             int          texture, 
    122                             int          texture_type); 
    123  
    124118void pack_yv12alpha(const unsigned char *source, 
    125119                 const unsigned char *dest, 
    126120                 const int *offsets,