Ticket #5324: openglvid_10.diff

File openglvid_10.diff, 32.6 KB (added by anonymous, 16 years ago)
  • libs/libmythtv/openglcontext.cpp

    diff -ur -X excl mythtvopengl9/libs/libmythtv/openglcontext.cpp mythtvopengl10/libs/libmythtv/openglcontext.cpp
    old new  
    4646    vector<GLuint> m_textures;
    4747    vector<GLuint> m_programs;
    4848    vector<GLuint> m_framebuffers;
     49    vector<GLuint> m_pbos;
    4950};
    5051
    5152OpenGLContext::OpenGLContext(QMutex *lock) :
     
    7273        DeletePrograms();
    7374        DeleteTextures();
    7475        DeleteFrameBuffers();
     76        DeletePBOs();
    7577    }
    7678
    7779    glFlush();
     
    259261        ((tex_type) ? kGLExtRect : 0) |
    260262        ((has_gl_fragment_program_support(m_extensions)) ?
    261263         kGLExtFragProg : 0) |
     264        ((has_gl_pixelbuffer_object_support(m_extensions)) ?
     265         kGLExtPBufObj : 0) |
    262266        ((has_gl_fbuffer_object_support(m_extensions)) ? kGLExtFBufObj : 0) |
    263267        ((minor >= 3) ? kGLXPBuffer : 0);
    264268
     
    723727
    724728    MakeCurrent(false);
    725729}
     730
     731void OpenGLContext::UpdatePBO(uint tex, uint pbo,
     732                             const VideoFrame *frame,
     733                             const unsigned char *alpha)
     734{
     735    MakeCurrent(true);
     736
     737    void *pboMemory;
     738    uint tex_size = frame->width * frame->height * 4;
     739
     740    glBindTexture(GetTextureType(), tex);
     741    gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
     742    gMythGLBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB,
     743                         tex_size, NULL, GL_STREAM_DRAW);
     744
     745    pboMemory = gMythGLMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
     746                                    GL_WRITE_ONLY);
     747
     748    pack_yv12alpha(frame, (unsigned char *)pboMemory, alpha);
     749
     750    gMythGLUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
     751
     752    glTexSubImage2D(GetTextureType(), 0, 0, 0, frame->width, frame->height,
     753                    GL_BGRA, GL_UNSIGNED_BYTE, 0);
     754
     755    gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
     756
     757    MakeCurrent(false);
     758}
     759
     760
     761uint OpenGLContext::CreatePBO(QSize size)
     762{
     763    MakeCurrent(true);
     764
     765    gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
     766    glTexImage2D(GetTextureType(), 0, GL_RGBA8, size.width(), size.height(),
     767                 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
     768
     769    GLuint tmp_pbo;
     770    gMythGLGenBuffersARB(1, &tmp_pbo);
     771
     772    gMythGLBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
     773
     774    Flush();
     775
     776    MakeCurrent(false);
     777
     778    if (tmp_pbo)
     779        m_priv->m_pbos.push_back(tmp_pbo);
     780
     781    return tmp_pbo;
     782}
     783
     784void OpenGLContext::DeletePBO(uint pbo)
     785{
     786    MakeCurrent(true);
     787
     788    vector<GLuint>::iterator it;
     789    for (it = m_priv->m_pbos.begin();
     790         it != m_priv->m_pbos.end(); it++)
     791    {
     792        if (*(it) == pbo)
     793        {
     794            GLuint glpbo = pbo;
     795            gMythGLDeleteBuffersARB(1, &glpbo);
     796            m_priv->m_pbos.erase(it);
     797            break;
     798        }
     799    }
     800
     801    Flush();
     802
     803    MakeCurrent(false);
     804}
     805
     806void OpenGLContext::DeletePBOs(void)
     807{
     808    vector<GLuint>::iterator it;
     809    for (it = m_priv->m_pbos.begin();
     810         it != m_priv->m_pbos.end(); it++)
     811    {
     812        gMythGLDeleteBuffersARB(1, &(*(it)));
     813    }
     814    m_priv->m_pbos.clear();
     815
     816    Flush();
     817}
     818
  • libs/libmythtv/openglcontext.h

    diff -ur -X excl mythtvopengl9/libs/libmythtv/openglcontext.h mythtvopengl10/libs/libmythtv/openglcontext.h
    old new  
    1111
    1212// MythTV headers
    1313#include "util-x11.h"
     14#include "frame.h"
    1415
    1516class OpenGLVideo;
    1617class PrivateContext;
     
    2122    kGLExtFragProg = 0x02,
    2223    kGLExtFBufObj  = 0x04,
    2324    kGLXPBuffer    = 0x08,
     25    kGLExtPBufObj  = 0x10,
    2426} GLFeatures;
    2527
    2628class OpenGLContext;
     
    7779
    7880    static bool IsGLXSupported(Display *display, uint major, uint minor);
    7981
     82    uint CreatePBO(QSize size);
     83    void DeletePBO(uint pbo);
     84    void UpdatePBO(uint tex, uint pbo,
     85                   const VideoFrame *frame,
     86                   const unsigned char *alpha = NULL);
     87
    8088  private:
    8189    void Init2DState(void);
    8290    bool IsGLXSupported(uint major, uint minor) const
     
    8896    void DeleteTextures(void);
    8997    void DeletePrograms(void);
    9098    void DeleteFrameBuffers(void);
     99    void DeletePBOs(void);
    91100
    92101    PrivateContext *m_priv;
    93102
     
    142151    bool IsFeatureSupported(GLFeatures) const { return false; }
    143152
    144153    static bool IsGLXSupported(Display*, uint, uint) { return false; }
     154
     155    uint CreatePBO(QSize);
     156    void DeletePBO(uint);
     157    void UpdatePBO(uint, uint, const VideoFrame*, const unsigned char*);
    145158};
    146159
    147160#endif //!USING_OPENGL
  • libs/libmythtv/openglvideo.cpp

    diff -ur -X excl mythtvopengl9/libs/libmythtv/openglvideo.cpp mythtvopengl10/libs/libmythtv/openglvideo.cpp
    old new  
    4444    useColourControl(false),  viewportControl(false),
    4545    inputTextureSize(0,0),    currentFrameNum(0),
    4646    inputUpdated(false),
    47 
     47    fastTexStreaming(false),  pixelBufferObject(0),
    4848    convertSize(0,0),         convertBuf(NULL),
    4949
    5050    videoResize(false),       videoResizeRect(0,0,0,0)
     
    6262{
    6363    ShutDownYUV2RGB();
    6464
     65    if (pixelBufferObject)
     66        gl_context->DeletePBO(pixelBufferObject);
     67    pixelBufferObject = 0;
     68
    6569    for (uint i = 0; i < inputTextures.size(); i++)
    6670        gl_context->DeleteTexture(inputTextures[i]);
    6771    inputTextures.clear();
     
    114118
    115119    SetViewPort(display_visible_rect.size());
    116120
     121    fastTexStreaming = gl_context->IsFeatureSupported(kGLExtPBufObj);
     122
    117123    if (osd)
    118124    {
    119125        QSize osdsize = display_visible_rect.size();
    120         QSize half_size(osdsize.width() >> 1, osdsize.height() >>1);
    121         GLuint alphatex = CreateVideoTexture(osdsize, inputTextureSize);
    122         GLuint utex = CreateVideoTexture(half_size, inputTextureSize);
    123         GLuint vtex = CreateVideoTexture(half_size, inputTextureSize);
    124         GLuint ytex = CreateVideoTexture(osdsize, inputTextureSize);
    125 
    126         if ((alphatex && ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGBA))
    127         {
    128             inputTextures.push_back(ytex);
    129             inputTextures.push_back(utex);
    130             inputTextures.push_back(vtex);
    131             inputTextures.push_back(alphatex);
    132             if (!AddFilter(kGLFilterResize))
     126        if (fastTexStreaming)
     127        {
     128            GLuint tex = CreateVideoTexture(osdsize, inputTextureSize);
     129            pixelBufferObject = gl_context->CreatePBO(osdsize);
     130
     131            if (tex && pixelBufferObject &&
     132                AddFilter(kGLFilterYUV2RGBA) &&
     133                AddFilter(kGLFilterResize))
     134            {
     135                inputTextures.push_back(tex);
     136            }
     137            else
     138            {
     139                Teardown();
     140                fastTexStreaming = false;
     141            }
     142        }
     143       
     144        if (!fastTexStreaming)
     145        {   
     146            QSize half_size(osdsize.width() >> 1, osdsize.height() >>1);
     147            GLuint alphatex = CreateVideoTexture(osdsize, inputTextureSize);
     148            GLuint utex = CreateVideoTexture(half_size, inputTextureSize);
     149            GLuint vtex = CreateVideoTexture(half_size, inputTextureSize);
     150            GLuint ytex = CreateVideoTexture(osdsize, inputTextureSize);
     151
     152            if ((alphatex && ytex && utex && vtex) &&
     153                 AddFilter(kGLFilterYUV2RGBA) &&
     154                 AddFilter(kGLFilterResize))
     155            {
     156                inputTextures.push_back(ytex);
     157                inputTextures.push_back(utex);
     158                inputTextures.push_back(vtex);
     159                inputTextures.push_back(alphatex);
     160            }
     161            else
    133162            {
    134163                Teardown();
    135                 return false;
    136164            }
    137165        }
    138166    }
    139167    else
    140168    {
    141         QSize half_size(actual_video_dim.width() >> 1,
    142                         actual_video_dim.height() >>1);
    143         GLuint utex = CreateVideoTexture(half_size, inputTextureSize);
    144         GLuint vtex = CreateVideoTexture(half_size, inputTextureSize);
    145         GLuint ytex = CreateVideoTexture(actual_video_dim, inputTextureSize);;
    146 
    147         if ((ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGB))
    148         {
    149             inputTextures.push_back(ytex);
    150             inputTextures.push_back(utex);
    151             inputTextures.push_back(vtex);
     169        if (fastTexStreaming)
     170        {
     171            GLuint tex = CreateVideoTexture(actual_video_dim, inputTextureSize);
     172            pixelBufferObject = gl_context->CreatePBO(actual_video_dim);
     173 
     174            if (tex && pixelBufferObject &&
     175                AddFilter(kGLFilterYUV2RGB))
     176            {
     177                inputTextures.push_back(tex);
     178            }
     179            else
     180            {
     181                Teardown();
     182                fastTexStreaming = false;
     183            }
     184        }
     185
     186        if (!fastTexStreaming)
     187        {
     188            QSize half_size(actual_video_dim.width() >> 1, actual_video_dim.height() >>1);
     189            GLuint utex = CreateVideoTexture(half_size, inputTextureSize);
     190            GLuint vtex = CreateVideoTexture(half_size, inputTextureSize);
     191            GLuint ytex = CreateVideoTexture(actual_video_dim, inputTextureSize);
     192
     193            if ((ytex && utex && vtex) && AddFilter(kGLFilterYUV2RGB))
     194            {
     195                inputTextures.push_back(ytex);
     196                inputTextures.push_back(utex);
     197                inputTextures.push_back(vtex);
     198            }
     199            else
     200            {
     201                Teardown();
     202            }
    152203        }
    153204    }
    154205
     
    180231        }
    181232    }
    182233
     234    if (fastTexStreaming)
     235        VERBOSE(VB_PLAYBACK, LOC + "Using PBO accelerated texture uploading.");
     236
    183237    return true;
    184238}
    185239
     
    352406    {
    353407        temp->numInputs = 2;
    354408    }
    355     else if ((filter == kGLFilterYUV2RGB) ||
     409    else if ((filter == kGLFilterYUV2RGB && !fastTexStreaming) ||
    356410             (filter == kGLFilterOneFieldDeintDFR) ||
    357411             (filter == kGLFilterKernelDeintDFR) ||
    358412             (filter == kGLFilterLinearBlendDeintDFR))
    359413    {
    360414        temp->numInputs = 3;
    361415    }
    362     else if ((filter == kGLFilterYUV2RGBA))
     416    else if ((filter == kGLFilterYUV2RGBA) && !fastTexStreaming)
    363417    {
    364418        temp->numInputs = 4;
    365419    }
     
    556610
    557611    if (filters.count(kGLFilterYUV2RGB) && (frame->codec == FMT_YV12))
    558612    {
    559         UpdateInput(frame->buf, frame->offsets, 0, FMT_YV12, actual_video_dim);
     613        if (fastTexStreaming && pixelBufferObject)
     614        {
     615            gl_context->UpdatePBO(inputTextures[0], pixelBufferObject,
     616                                  frame);
     617            inputUpdated = true;
     618            return;
     619        }
     620
     621        UpdateInput(frame->buf, frame->offsets, FMT_YV12, actual_video_dim);
    560622        return;
    561623    }
    562624
     
    585647                    convertSize.width(), convertSize.height());
    586648
    587649        int offset = 0;
    588         UpdateInput(convertBuf, &offset, 0, FMT_RGB24, convertSize);
     650        UpdateInput(convertBuf, &offset, FMT_RGB24, convertSize);
    589651    }
    590652}
    591653
    592654// locking ok
    593655void OpenGLVideo::UpdateInput(const unsigned char *buf, const int *offsets,
    594                               uint texture_index, int format, QSize size)
     656                              int format, QSize size,
     657                              const unsigned char *alpha)
    595658{
    596659    ContextLocker ctx_lock(gl_context);
    597660
    598661    inputUpdated = false;
    599662
    600     if (texture_index >= inputTextures.size())
     663    if (fastTexStreaming && pixelBufferObject &&
     664        FMT_YV12 == format && alpha)
     665    {
     666        VideoFrame frame;
     667        frame.codec = FMT_YV12;
     668        frame.buf = (unsigned char *)buf;
     669        frame.width = size.width();
     670        frame.height = size.height();
     671        frame.offsets[0] = offsets[0];
     672        frame.offsets[1] = offsets[1];
     673        frame.offsets[2] = offsets[2];
     674        frame.pitches[0] = size.width();
     675        frame.pitches[1] = size.width() >> 1;
     676        frame.pitches[2] = size.width() >> 1;
     677        gl_context->UpdatePBO(inputTextures[0], pixelBufferObject,
     678                              &frame, alpha);
     679
     680        inputUpdated = true;
    601681        return;
     682    }
    602683
    603684    copy_pixels_to_texture(
    604685        buf + offsets[0], format, size,
    605         inputTextures[texture_index], gl_context->GetTextureType());
     686        inputTextures[0], gl_context->GetTextureType());
    606687
    607688    if (FMT_YV12 == format)
    608689    {
    609690        QSize chroma_size(size.width() >> 1, size.height() >> 1);
    610691        copy_pixels_to_texture(
    611692            buf + offsets[1], format, chroma_size,
    612             inputTextures[texture_index + 1],
     693            inputTextures[1],
    613694            gl_context->GetTextureType());
    614695        copy_pixels_to_texture(
    615696            buf + offsets[2], format, chroma_size,
    616             inputTextures[texture_index + 2],
     697            inputTextures[2],
    617698            gl_context->GetTextureType());
     699        if (alpha)
     700        {
     701            copy_pixels_to_texture(
     702                alpha, FMT_ALPHA, size,
     703                inputTextures[3],
     704                gl_context->GetTextureType());
     705        }
    618706    }
    619707
    620708    inputUpdated = true;
     
    9281016                            pictureAttribs[kPictureAttribute_Brightness],
    9291017                            pictureAttribs[kPictureAttribute_Contrast],
    9301018                            pictureAttribs[kPictureAttribute_Colour],
    931                             0.0f);
     1019                            0.5f);
    9321020                    }
    9331021                    break;
    9341022
     
    9581046            glEnable(GL_BLEND);
    9591047
    9601048        // draw quad
     1049        bool multi = ((type == kGLFilterYUV2RGB ||
     1050                       type == kGLFilterYUV2RGBA) &&
     1051                       !fastTexStreaming);
     1052        bool multi_alpha = multi && (type == kGLFilterYUV2RGBA);
     1053
    9611054        glBegin(GL_QUADS);
    9621055        glTexCoord2f(t_left, t_top);
    963         if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
     1056        if (multi)
    9641057        {
    9651058            glMultiTexCoord2f(GL_TEXTURE1, t_left_uv, t_top_uv);
    9661059            glMultiTexCoord2f(GL_TEXTURE2, t_left_uv, t_top_uv);
    967             if (type == kGLFilterYUV2RGBA)
     1060            if (multi_alpha)
    9681061                glMultiTexCoord2f(GL_TEXTURE3, t_left_uv, t_top_uv);
    9691062        }
    9701063        glVertex2f(vleft,  vtop);
    9711064
    9721065        glTexCoord2f(t_right, t_top);
    973         if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
     1066        if (multi)
    9741067        {
    9751068            glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_top_uv);
    9761069            glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_top_uv);
    977             if (type == kGLFilterYUV2RGBA)
     1070            if (multi_alpha)
    9781071                glMultiTexCoord2f(GL_TEXTURE3, t_right, t_top);
    9791072        }
    9801073        glVertex2f(vright, vtop);
    9811074
    9821075        glTexCoord2f(t_right, t_bottom);
    983         if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
     1076        if (multi)
    9841077        {
    9851078            glMultiTexCoord2f(GL_TEXTURE1, t_right_uv, t_bottom_uv);
    9861079            glMultiTexCoord2f(GL_TEXTURE2, t_right_uv, t_bottom_uv);
    987             if (type == kGLFilterYUV2RGBA)
     1080            if (multi_alpha)
    9881081                glMultiTexCoord2f(GL_TEXTURE3, t_right, t_bottom);
    9891082        }
    9901083        glVertex2f(vright, vbot);
    9911084
    9921085        glTexCoord2f(t_left, t_bottom);
    993         if (type == kGLFilterYUV2RGB || type == kGLFilterYUV2RGBA)
     1086        if (multi)
    9941087        {
    9951088            glMultiTexCoord2f(GL_TEXTURE1, t_left_uv, t_bottom_uv);
    9961089            glMultiTexCoord2f(GL_TEXTURE2, t_left_uv, t_bottom_uv);
    997             if (type == kGLFilterYUV2RGBA)
     1090            if (multi_alpha)
    9981091                glMultiTexCoord2f(GL_TEXTURE3, t_left_uv, t_bottom);
    9991092        }
    10001093        glVertex2f(vleft,  vbot);
     
    11511244    return "";
    11521245}
    11531246
    1154 static const QString yuv2rgb1a =
     1247static const QString init_norm =
    11551248"ATTRIB ytex  = fragment.texcoord[0];"
    11561249"ATTRIB uvtex = fragment.texcoord[1];"
    11571250"TEMP res, tmp;";
    11581251
    1159 static const QString yuv2rgb1b =
     1252static const QString init_alpha =
    11601253"TEMP alpha;"
    11611254"TEX alpha, ytex, texture[3], %1;";
    11621255
    1163 static const QString yuv2rgb1c =
     1256static const QString tex_sample =
    11641257"TEX res,   ytex,  texture[0], %1;"
    11651258"TEX tmp.x, uvtex, texture[1], %1;"
    11661259"TEX tmp.y, uvtex, texture[2], %1;";
    11671260
    1168 static const QString yuv2rgb2 =
     1261static const QString colour_control =
    11691262"PARAM  adj  = program.env[0];"
    11701263"SUB res, res, 0.5;"
    11711264"MAD res, res, adj.yyyy, adj.xxxx;"
    11721265"SUB tmp, tmp, { 0.5, 0.5 };"
    11731266"MAD tmp, adj.zzzz, tmp, 0.5;";
    11741267
    1175 static const QString yuv2rgb3 =
     1268static const QString colour_control_fast =
     1269"PARAM  adj  = program.env[0];"
     1270"SUB res, res, 0.5;"
     1271"MAD res, res, adj.zzzy, adj.wwwx;";
     1272
     1273static const QString end_norm =
    11761274"MAD res, res, 1.164, -0.063;"
    11771275"SUB tmp, tmp, { 0.5, 0.5 };"
    11781276"MAD res, { 0, -.392, 2.017 }, tmp.xxxw, res;"
    11791277"MAD result.color, { 1.596, -.813, 0, 0 }, tmp.yyyw, res;";
    11801278
    1181 static const QString yuv2rgb4 =
     1279static const QString end_alpha =
    11821280"MOV result.color.a, alpha.a;";
    11831281
     1282static const QString init_fast =
     1283"ATTRIB tex  = fragment.texcoord[0];"
     1284"TEMP tmp, res;"
     1285"TEX res, tex, texture[0], %1;";
     1286
     1287static const QString init_fast_alpha =
     1288"MOV result.color.a, res.g;";
     1289
     1290static const QString end_fast =
     1291"SUB tmp, res.rbgg, { 0.5, 0.5 };"
     1292"MAD res, res.a, 1.164, -0.063;"
     1293"MAD res, { 0, -.392, 2.017 }, tmp.xxxw, res;"
     1294"MAD result.color, { 1.596, -.813, 0, 0 }, tmp.yyyw, res;";
     1295
     1296static const QString end_fast_alpha =
     1297"SUB tmp, res.rbgg, { 0.5, 0.5 };"
     1298"MAD res, res.a, 1.164, -0.063;"
     1299"MAD res, { 0, -.392, 2.017 }, tmp.xxxw, res;"
     1300"MAD result.color.rgb, { 1.596, -.813, 0, 0 }, tmp.yyyw, res;";
     1301
    11841302// locking ok
    11851303QString OpenGLVideo::GetProgramString(OpenGLFilterType name)
    11861304{
     
    11911309    switch (name)
    11921310    {
    11931311        case kGLFilterYUV2RGB:
    1194             ret = ret + yuv2rgb1a + yuv2rgb1c;
    1195             if (useColourControl)
    1196                 ret += yuv2rgb2;
    1197             ret += yuv2rgb3;
     1312            if (fastTexStreaming)
     1313            {
     1314                ret += init_fast;
     1315                if (useColourControl)
     1316                    ret += colour_control_fast;
     1317                ret += end_fast;
     1318            }
     1319            else
     1320            {
     1321                ret = ret + init_norm + tex_sample;
     1322                if (useColourControl)
     1323                    ret += colour_control;
     1324                ret += end_norm;
     1325            }
    11981326            break;
    11991327
    12001328        case kGLFilterYUV2RGBA:
    1201             ret = ret + yuv2rgb1a + yuv2rgb1b + yuv2rgb1c;
    1202             if (useColourControl)
    1203                 ret += yuv2rgb2;
    1204             ret = ret + yuv2rgb3 + yuv2rgb4;
     1329            if (fastTexStreaming)
     1330            {
     1331                ret += init_fast + init_fast_alpha;
     1332                if (useColourControl)
     1333                    ret += colour_control_fast;
     1334                ret += end_fast_alpha;
     1335            }
     1336            else
     1337            {
     1338                ret = ret + init_norm + init_alpha + tex_sample;
     1339                if (useColourControl)
     1340                    ret += colour_control;
     1341                ret = ret + end_norm + end_alpha;
     1342            }
    12051343            break;
    12061344
    12071345        case kGLFilterKernelDeint:
  • libs/libmythtv/openglvideo.h

    diff -ur -X excl mythtvopengl9/libs/libmythtv/openglvideo.h mythtvopengl10/libs/libmythtv/openglvideo.h
    old new  
    6161
    6262    void UpdateInputFrame(const VideoFrame *frame);
    6363    void UpdateInput(const unsigned char *buf, const int *offsets,
    64                      uint texture_index, int format, QSize size);
     64                     int format, QSize size,
     65                     const unsigned char *alpha = NULL);
    6566
    6667    bool AddFilter(const QString &filter)
    6768         { return AddFilter(StringToFilter(filter)); }
     
    128129    glfilt_map_t   filters;
    129130    long long      currentFrameNum;
    130131    bool           inputUpdated;
     132    bool           fastTexStreaming;
     133    uint           pixelBufferObject;
    131134
    132135    QSize            convertSize;
    133136    unsigned char   *convertBuf;
     
    151154        { (void) osd; return false; }
    152155
    153156    void UpdateInputFrame(const VideoFrame*) { }
    154     void UpdateInput(const unsigned char*, const int*, uint, int, QSize) { }
     157    void UpdateInput(const unsigned char*, const int*, int, QSize, unsigned char* = NULL) { }
    155158
    156159    bool AddFilter(const QString&) { return false; }
    157160    bool RemoveFilter(const QString&) { return false; }
  • libs/libmythtv/util-opengl.cpp

    diff -ur -X excl mythtvopengl9/libs/libmythtv/util-opengl.cpp mythtvopengl10/libs/libmythtv/util-opengl.cpp
    old new  
    33#include "util-opengl.h"
    44#include "frame.h"
    55
     6#ifdef MMX
     7extern "C" {
     8#include "libavcodec/i386/mmx.h"
     9}
     10#endif
     11
     12PFNGLMAPBUFFERPROC                  gMythGLMapBufferARB      = NULL;
     13PFNGLBINDBUFFERARBPROC              gMythGLBindBufferARB     = NULL;
     14PFNGLGENBUFFERSARBPROC              gMythGLGenBuffersARB     = NULL;
     15PFNGLBUFFERDATAARBPROC              gMythGLBufferDataARB     = NULL;
     16PFNGLUNMAPBUFFERARBPROC             gMythGLUnmapBufferARB    = NULL;
     17PFNGLDELETEBUFFERSARBPROC           gMythGLDeleteBuffersARB  = NULL;
     18
    619PFNGLGENPROGRAMSARBPROC             gMythGLGenProgramsARB            = NULL;
    720PFNGLBINDPROGRAMARBPROC             gMythGLBindProgramARB            = NULL;
    821PFNGLPROGRAMSTRINGARBPROC           gMythGLProgramStringARB          = NULL;
     
    3043
    3144    is_initialized = true;
    3245
     46    gMythGLMapBufferARB = (PFNGLMAPBUFFERPROC)
     47        get_gl_proc_address("glMapBufferARB");
     48    gMythGLBindBufferARB = (PFNGLBINDBUFFERARBPROC)
     49        get_gl_proc_address("glBindBufferARB");
     50    gMythGLGenBuffersARB = (PFNGLGENBUFFERSARBPROC)
     51        get_gl_proc_address("glGenBuffersARB");
     52    gMythGLBufferDataARB = (PFNGLBUFFERDATAARBPROC)
     53        get_gl_proc_address("glBufferDataARB");
     54    gMythGLUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)
     55        get_gl_proc_address("glUnmapBufferARB");
     56    gMythGLDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)
     57        get_gl_proc_address("glDeleteBuffersARB");
     58
    3359    gMythGLGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)
    3460        get_gl_proc_address("glGenProgramsARB");
    3561    gMythGLBindProgramARB = (PFNGLBINDPROGRAMARBPROC)
     
    369395
    370396    return gMythGLXGetVideoSyncSGI && gMythGLXWaitVideoSyncSGI;
    371397}
     398
     399bool has_gl_pixelbuffer_object_support(const QString &ext)
     400{
     401    init_opengl();
     402
     403    if (!ext.contains("GL_EXT_pixel_buffer_object"))
     404        return false;
     405
     406    return (gMythGLMapBufferARB     &&
     407            gMythGLBindBufferARB    &&
     408            gMythGLGenBuffersARB    &&
     409            gMythGLDeleteBuffersARB &&
     410            gMythGLBufferDataARB    &&
     411            gMythGLUnmapBufferARB);
     412}
     413
     414#ifdef MMX
     415static inline void mmx_pack_alpha_high(uint8_t *a1, uint8_t *a2)
     416{
     417    movq_m2r (*a1, mm4);
     418    punpckhbw_r2r (mm0, mm4);
     419    movq_m2r (*a2, mm7);
     420    punpckhbw_r2r (mm1, mm7);
     421}
     422
     423static inline void mmx_pack_alpha_low(uint8_t *a1, uint8_t *a2)
     424{
     425    movq_m2r (*a1, mm4);
     426    punpcklbw_r2r (mm0, mm4);
     427    movq_m2r (*a2, mm7);
     428    punpcklbw_r2r (mm1, mm7);
     429}
     430
     431static mmx_t mmx_1s = {0xffffffffffffffffLL};
     432
     433static inline void mmx_pack_alpha1s_high(void)
     434{
     435    movq_m2r (mmx_1s, mm4);
     436    punpckhbw_r2r (mm0, mm4);
     437    movq_m2r (mmx_1s, mm7);
     438    punpckhbw_r2r (mm1, mm7);
     439}
     440
     441static inline void mmx_pack_alpha1s_low(void)
     442{
     443    movq_m2r (mmx_1s, mm4);
     444    punpcklbw_r2r (mm0, mm4);
     445    movq_m2r (mmx_1s, mm7);
     446    punpcklbw_r2r (mm1, mm7);
     447}
     448
     449static inline void mmx_pack_start(uint8_t *y1, uint8_t *y2,
     450                            uint8_t *u,  uint8_t *v,
     451                            uint8_t *dest1, uint8_t *dest2)
     452{
     453    movq_m2r (*y1, mm0);
     454    movq_m2r (*y2, mm1);
     455    movd_m2r (*u,  mm2);
     456    movd_m2r (*v,  mm3);
     457
     458    punpcklbw_r2r (mm2, mm2);
     459    punpcklbw_r2r (mm3, mm3);
     460}
     461
     462static inline void mmx_pack_middle(uint8_t *dest1, uint8_t *dest2)
     463{
     464    movq_r2r (mm3, mm5);
     465    punpcklbw_r2r (mm2, mm5);
     466
     467    movq_r2r (mm5, mm6);
     468    punpcklbw_r2r (mm4, mm6);
     469    movq_r2m (mm6, *(dest1));
     470
     471    movq_r2r (mm5, mm6);
     472    punpckhbw_r2r (mm4, mm6);
     473    movq_r2m (mm6, *(dest1 + 8));
     474
     475    movq_r2r (mm5, mm6);
     476    punpcklbw_r2r (mm7, mm6);
     477    movq_r2m (mm6, *(dest2));
     478
     479    movq_r2r (mm5, mm6);
     480    punpckhbw_r2r (mm7, mm6);
     481    movq_r2m (mm6, *(dest2 + 8));
     482}
     483
     484static inline void mmx_pack_end(uint8_t *dest1, uint8_t *dest2)
     485{
     486    movq_r2r (mm3, mm5);
     487    punpckhbw_r2r (mm2, mm5);
     488
     489    movq_r2r (mm5, mm6);
     490    punpcklbw_r2r (mm4, mm6);
     491    movq_r2m (mm6, *(dest1 + 16));
     492
     493    movq_r2r (mm5, mm6);
     494    punpckhbw_r2r (mm4, mm6);
     495    movq_r2m (mm6, *(dest1 + 24));
     496
     497    movq_r2r (mm5, mm6);
     498    punpcklbw_r2r (mm7, mm6);
     499    movq_r2m (mm6, *(dest2 + 16));
     500
     501    movq_r2r (mm5, mm6);
     502    punpckhbw_r2r (mm7, mm6);
     503    movq_r2m (mm6, *(dest2 + 24));
     504}
     505#endif // MMX
     506
     507void pack_yv12alpha(const VideoFrame    *frame,
     508                    const unsigned char *buf,
     509                    const unsigned char *alpha)
     510{
     511    if (frame->codec != FMT_YV12 || (frame->height % 2))
     512        return;
     513
     514    uint bgra_width  = frame->width << 2;
     515    uint chroma_width = frame->width >> 1;
     516    uint u_extra     = frame->pitches[1] - chroma_width;
     517    uint v_extra     = frame->pitches[2] - chroma_width;
     518
     519    uint8_t *ypt_1   = (uint8_t *)frame->buf + frame->offsets[0];
     520    uint8_t *ypt_2   = ypt_1 + frame->width;
     521    uint8_t *upt     = (uint8_t *)frame->buf + frame->offsets[1];
     522    uint8_t *vpt     = (uint8_t *)frame->buf + frame->offsets[2];
     523    uint8_t *dst_1   = (uint8_t *) buf;
     524    uint8_t *dst_2   = dst_1 + bgra_width;
     525
     526    if (alpha)
     527    {
     528        uint8_t *alpha_1 = (uint8_t *) alpha;
     529        uint8_t *alpha_2 = alpha_1 + frame->width;
     530
     531#ifdef MMX
     532        if (!(frame->width % 8))
     533        {
     534            for (int row = 0; row < frame->height; row += 2)
     535            {
     536                for (int col = 0; col < frame->width; col += 8)
     537                {
     538                    mmx_pack_start(ypt_1, ypt_2, upt,  vpt, dst_1, dst_2);
     539                    mmx_pack_alpha_low(alpha_1, alpha_2);
     540                    mmx_pack_middle(dst_1, dst_2);
     541                    mmx_pack_alpha_high(alpha_1, alpha_2);
     542                    mmx_pack_end(dst_1, dst_2);
     543                    dst_1 += 32;
     544                    dst_2 += 32;
     545                    alpha_1 += 8;
     546                    alpha_2 += 8;
     547                    ypt_1 += 8;
     548                    ypt_2 += 8;
     549                    upt   += 4;
     550                    vpt   += 4;
     551                }
     552                ypt_1 += (frame->pitches[0]);
     553                ypt_2 += (frame->pitches[0]);
     554                upt   += u_extra;
     555                vpt   += v_extra;
     556                dst_1 += bgra_width;
     557                dst_2 += bgra_width;
     558                alpha_1 += frame->width;
     559                alpha_2 += frame->width;
     560            }
     561
     562            emms();
     563
     564            return;
     565        }
     566#endif //MMX
     567
     568        for (int row = 0; row < frame->height; row += 2)
     569        {
     570            for (int col = 0; col < frame->width; col += 2)
     571            {
     572                *(dst_1++) = *vpt;
     573                *(dst_2++) = *vpt;
     574                *(dst_1++) = *(alpha_1++);
     575                *(dst_2++) = *(alpha_2++);
     576                *(dst_1++) = *upt;
     577                *(dst_2++) = *upt;
     578                *(dst_1++) = *(ypt_1++);
     579                *(dst_2++) = *(ypt_2++);
     580
     581                *(dst_1++) = *vpt;
     582                *(dst_2++) = *(vpt++);
     583                *(dst_1++) = *(alpha_1++);
     584                *(dst_2++) = *(alpha_2++);
     585                *(dst_1++) = *upt;
     586                *(dst_2++) = *(upt++);
     587                *(dst_1++) = *(ypt_1++);
     588                *(dst_2++) = *(ypt_2++);
     589            }
     590            ypt_1   += (frame->pitches[0]);
     591            ypt_2   += (frame->pitches[0]);
     592            upt     += u_extra;
     593            vpt     += v_extra;
     594            alpha_1 += frame->width;
     595            alpha_2 += frame->width;
     596            dst_1   += bgra_width;
     597            dst_2   += bgra_width;
     598        }
     599    }
     600    else
     601    {
     602
     603#ifdef MMX
     604       if (!(frame->width % 8))
     605        {
     606            for (int row = 0; row < frame->height; row += 2)
     607            {
     608                for (int col = 0; col < frame->width; col += 8)
     609                {
     610                    mmx_pack_start(ypt_1, ypt_2, upt,  vpt, dst_1, dst_2);
     611                    mmx_pack_alpha1s_low();
     612                    mmx_pack_middle(dst_1, dst_2);
     613                    mmx_pack_alpha1s_high();
     614                    mmx_pack_end(dst_1, dst_2);
     615                    dst_1 += 32;
     616                    dst_2 += 32;
     617                    ypt_1 += 8;
     618                    ypt_2 += 8;
     619                    upt   += 4;
     620                    vpt   += 4;
     621                }
     622                ypt_1 += (frame->pitches[0]);
     623                ypt_2 += (frame->pitches[0]);
     624                upt   += u_extra;
     625                vpt   += v_extra;
     626                dst_1 += bgra_width;
     627                dst_2 += bgra_width;
     628            }
     629
     630            emms();
     631
     632            return;
     633        }
     634#endif //MMX
     635
     636        for (int row = 0; row < frame->height; row += 2)
     637        {
     638            for (int col = 0; col < frame->width; col += 2)
     639            {
     640                *(dst_1++) = *vpt;
     641                *(dst_2++) = *vpt;
     642                *(dst_1++) = 255;
     643                *(dst_2++) = 255;
     644                *(dst_1++) = *upt;
     645                *(dst_2++) = *upt;
     646                *(dst_1++) = *(ypt_1++);
     647                *(dst_2++) = *(ypt_2++);
     648
     649                *(dst_1++) = *vpt;
     650                *(dst_2++) = *(vpt++);
     651                *(dst_1++) = 255;
     652                *(dst_2++) = 255;
     653                *(dst_1++) = *upt;
     654                *(dst_2++) = *(upt++);
     655                *(dst_1++) = *(ypt_1++);
     656                *(dst_2++) = *(ypt_2++);
     657            }
     658            ypt_1   += (frame->pitches[0]);
     659            ypt_2   += (frame->pitches[0]);
     660            upt     += u_extra;
     661            vpt     += v_extra;
     662            dst_1   += bgra_width;
     663            dst_2   += bgra_width;
     664        }
     665    }
     666}
     667
  • libs/libmythtv/util-opengl.h

    diff -ur -X excl mythtvopengl9/libs/libmythtv/util-opengl.h mythtvopengl10/libs/libmythtv/util-opengl.h
    old new  
    88// MythTV headers
    99#include "mythcontext.h"
    1010#include "util-x11.h"
     11#include "frame.h"
    1112
    1213// GLX headers
    1314#define GLX_GLXEXT_PROTOTYPES
     
    128129                            int          texture,
    129130                            int          texture_type);
    130131
     132void pack_yv12alpha(const VideoFrame    *frame,
     133                const unsigned char *buf,
     134                const unsigned char *alpha = NULL);
     135
    131136__GLXextFuncPtr get_gl_proc_address(const QString &procName);
    132137
    133138int get_gl_texture_rect_type(const QString &extensions);
    134139bool has_gl_fbuffer_object_support(const QString &extensions);
    135140bool has_gl_fragment_program_support(const QString &extensions);
    136141bool has_glx_video_sync_support(const QString &glx_extensions);
     142bool has_gl_pixelbuffer_object_support(const QString &extensions);
    137143
    138144extern QString                             gMythGLExtensions;
    139145extern uint                                gMythGLExtSupported;
     
    145151extern PFNGLDELETEPROGRAMSARBPROC          gMythGLDeleteProgramsARB;
    146152extern PFNGLGETPROGRAMIVARBPROC            gMythGLGetProgramivARB;
    147153
     154extern PFNGLMAPBUFFERPROC                  gMythGLMapBufferARB;
     155extern PFNGLBINDBUFFERARBPROC              gMythGLBindBufferARB;
     156extern PFNGLGENBUFFERSARBPROC              gMythGLGenBuffersARB;
     157extern PFNGLBUFFERDATAARBPROC              gMythGLBufferDataARB;
     158extern PFNGLUNMAPBUFFERARBPROC             gMythGLUnmapBufferARB;
     159extern PFNGLDELETEBUFFERSARBPROC           gMythGLDeleteBuffersARB;
     160
    148161// Not all platforms with OpenGL that MythTV supports have the
    149162// GL_EXT_framebuffer_object extension so we need to define these..
    150163typedef void (APIENTRYP MYTH_GLGENFRAMEBUFFERSEXTPROC)
  • libs/libmythtv/videoout_xv.cpp

    diff -ur -X excl mythtvopengl9/libs/libmythtv/videoout_xv.cpp mythtvopengl10/libs/libmythtv/videoout_xv.cpp
    old new  
    42124212            surface->v - surface->yuvbuffer,
    42134213        };
    42144214        gl_osdchain->UpdateInput(surface->yuvbuffer, offsets,
    4215                                  0, FMT_YV12, visible);
    4216         gl_osdchain->UpdateInput(surface->alpha, offsets,
    4217                                  3, FMT_ALPHA, visible);
     4215                                 FMT_YV12, visible, surface->alpha);
    42184216    }
    42194217    return changed;
    42204218}