Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[osx] refactor vda to pass cvbufrefs up for rendering, decreases CPU …

…from 55 to 35 percent when decoding 1080p via vda
  • Loading branch information...
commit 1e941981510f28bee9012b4278ce48ab026a433b 1 parent eac347e
davilla authored
211 xbmc/cores/VideoRenderers/LinuxRendererGL.cpp
@@ -64,6 +64,18 @@
64 64
65 65 #endif
66 66
  67 +#ifdef TARGET_DARWIN
  68 +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
  69 + #include <CoreVideo/CoreVideo.h>
  70 + #include <OpenGL/CGLIOSurface.h>
  71 +#else
  72 + enum CVPixelBufferLockFlags {
  73 + kCVPixelBufferLock_ReadOnly = 0x00000001,
  74 + };
  75 + #include <CoreVideo/CVPixelBuffer.h>
  76 +#endif
  77 +#endif
  78 +
67 79 #ifdef HAS_GLX
68 80 #include <GL/glx.h>
69 81 #endif
@@ -136,7 +148,12 @@ CLinuxRendererGL::CLinuxRendererGL()
136 148 {
137 149 m_textureTarget = GL_TEXTURE_2D;
138 150 for (int i = 0; i < NUM_BUFFERS; i++)
  151 + {
139 152 m_eventTexturesDone[i] = new CEvent(false,true);
  153 +#ifdef TARGET_DARWIN
  154 + m_buffers[i].cvBufferRef = NULL;
  155 +#endif
  156 + }
140 157
141 158 m_renderMethod = RENDER_GLSL;
142 159 m_renderQuality = RQ_SINGLEPASS;
@@ -765,6 +782,9 @@ unsigned int CLinuxRendererGL::PreInit()
765 782 m_formats.push_back(RENDER_FMT_NV12);
766 783 m_formats.push_back(RENDER_FMT_YUYV422);
767 784 m_formats.push_back(RENDER_FMT_UYVY422);
  785 +#ifdef TARGET_DARWIN
  786 + m_formats.push_back(RENDER_FMT_CVBREF);
  787 +#endif
768 788
769 789 // setup the background colour
770 790 m_clearColour = (float)(g_advancedSettings.m_videoBlackBarColour & 0xff) / 0xff;
@@ -925,6 +945,11 @@ void CLinuxRendererGL::LoadShaders(int field)
925 945 CLog::Log(LOGNOTICE, "GL: Using VAAPI render method");
926 946 m_renderMethod = RENDER_VAAPI;
927 947 }
  948 + else if (m_format == RENDER_FMT_CVBREF)
  949 + {
  950 + CLog::Log(LOGNOTICE, "GL: Using CoreVideoRef render method");
  951 + m_renderMethod = RENDER_CVREF;
  952 + }
928 953 else
929 954 {
930 955 int requestedMethod = g_guiSettings.GetInt("videoplayer.rendermethod");
@@ -1025,7 +1050,9 @@ void CLinuxRendererGL::LoadShaders(int field)
1025 1050 CLog::Log(LOGNOTICE, "GL: NPOT texture support detected");
1026 1051
1027 1052
1028   - if (m_pboSupported && !(m_renderMethod & RENDER_SW))
  1053 + if (m_pboSupported &&
  1054 + !(m_renderMethod & RENDER_SW) &&
  1055 + !(m_renderMethod & RENDER_CVREF))
1029 1056 {
1030 1057 CLog::Log(LOGNOTICE, "GL: Using GL_ARB_pixel_buffer_object");
1031 1058 m_pboUsed = true;
@@ -1059,6 +1086,12 @@ void CLinuxRendererGL::LoadShaders(int field)
1059 1086 m_textureCreate = &CLinuxRendererGL::CreateVAAPITexture;
1060 1087 m_textureDelete = &CLinuxRendererGL::DeleteVAAPITexture;
1061 1088 }
  1089 + else if (m_format == RENDER_FMT_CVBREF)
  1090 + {
  1091 + m_textureUpload = &CLinuxRendererGL::UploadCVRefTexture;
  1092 + m_textureCreate = &CLinuxRendererGL::CreateCVRefTexture;
  1093 + m_textureDelete = &CLinuxRendererGL::DeleteCVRefTexture;
  1094 + }
1062 1095 else
1063 1096 {
1064 1097 // setup default YV12 texture handlers
@@ -1159,6 +1192,12 @@ void CLinuxRendererGL::Render(DWORD flags, int renderBuffer)
1159 1192 RenderVAAPI(renderBuffer, m_currentField);
1160 1193 }
1161 1194 #endif
  1195 +#ifdef TARGET_DARWIN
  1196 + else if (m_renderMethod & RENDER_CVREF)
  1197 + {
  1198 + RenderCoreVideoRef(renderBuffer, m_currentField);
  1199 + }
  1200 +#endif
1162 1201 else
1163 1202 {
1164 1203 RenderSoftware(renderBuffer, m_currentField);
@@ -1625,6 +1664,38 @@ void CLinuxRendererGL::RenderVAAPI(int index, int field)
1625 1664 #endif
1626 1665 }
1627 1666
  1667 +void CLinuxRendererGL::RenderCoreVideoRef(int index, int field)
  1668 +{
  1669 +#ifdef TARGET_DARWIN
  1670 + YUVPLANE &plane = m_buffers[index].fields[field][0];
  1671 +
  1672 + glDisable(GL_DEPTH_TEST);
  1673 +
  1674 + // Y
  1675 + glEnable(GL_TEXTURE_RECTANGLE_ARB);
  1676 + glActiveTextureARB(GL_TEXTURE0);
  1677 + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, plane.id);
  1678 + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  1679 +
  1680 + glBegin(GL_QUADS);
  1681 + glTexCoord2f(plane.rect.x1, plane.rect.y1);
  1682 + glVertex4f(m_destRect.x1, m_destRect.y1, 0, 1.0f );
  1683 +
  1684 + glTexCoord2f(plane.rect.x2, plane.rect.y1);
  1685 + glVertex4f(m_destRect.x2, m_destRect.y1, 0, 1.0f);
  1686 +
  1687 + glTexCoord2f(plane.rect.x2, plane.rect.y2);
  1688 + glVertex4f(m_destRect.x2, m_destRect.y2, 0, 1.0f);
  1689 +
  1690 + glTexCoord2f(plane.rect.x1, plane.rect.y2);
  1691 + glVertex4f(m_destRect.x1, m_destRect.y2, 0, 1.0f);
  1692 +
  1693 + glEnd();
  1694 +
  1695 + glDisable(GL_TEXTURE_RECTANGLE_ARB);
  1696 +#endif
  1697 +}
  1698 +
1628 1699 void CLinuxRendererGL::RenderSoftware(int index, int field)
1629 1700 {
1630 1701 YUVPLANES &planes = m_buffers[index].fields[field];
@@ -2400,6 +2471,132 @@ void CLinuxRendererGL::UploadVAAPITexture(int index)
2400 2471 #endif
2401 2472 }
2402 2473
  2474 +//********************************************************************************************************
  2475 +// CoreVideoRef Texture creation, deletion, copying + clearing
  2476 +//********************************************************************************************************
  2477 +void CLinuxRendererGL::UploadCVRefTexture(int index)
  2478 +{
  2479 +#ifdef TARGET_DARWIN
  2480 + CVBufferRef cvBufferRef = m_buffers[index].cvBufferRef;
  2481 +
  2482 + if (cvBufferRef)
  2483 + {
  2484 + YUVFIELDS &fields = m_buffers[index].fields;
  2485 + YUVPLANE &plane = fields[0][0];
  2486 +
  2487 +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
  2488 + CVPixelBufferLockBaseAddress(cvBufferRef, kCVPixelBufferLock_ReadOnly);
  2489 + int bufferWidth = CVPixelBufferGetWidth(cvBufferRef);
  2490 + int bufferHeight = CVPixelBufferGetHeight(cvBufferRef);
  2491 + unsigned char *bufferBase = (unsigned char *)CVPixelBufferGetBaseAddress(cvBufferRef);
  2492 +
  2493 + glEnable(GL_TEXTURE_RECTANGLE_ARB);
  2494 + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, plane.id);
  2495 + // Set storage hint. Can also use GL_STORAGE_SHARED_APPLE see docs.
  2496 + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_CACHED_APPLE);
  2497 + // Using GL_YCBCR_422_APPLE extension to pull in video frame data directly
  2498 + glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, bufferWidth, bufferHeight, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, bufferBase);
  2499 + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
  2500 + glDisable(GL_TEXTURE_RECTANGLE_ARB);
  2501 +
  2502 + CVPixelBufferUnlockBaseAddress(cvBufferRef, kCVPixelBufferLock_ReadOnly);
  2503 +#else
  2504 + // CGLTexImageIOSurface2D only exits in 10.5sdk and above.
  2505 + // It is the fastest way to render a CVPixelBuffer backed
  2506 + // with an IOSurface as there is no CPU -> GPU upload.
  2507 + CGLContextObj cgl_ctx = (CGLContextObj)g_Windowing.GetCGLContextObj();
  2508 + IOSurfaceRef surface = CVPixelBufferGetIOSurface(cvBufferRef);
  2509 + GLsizei texWidth = IOSurfaceGetWidth(surface);
  2510 + GLsizei texHeight= IOSurfaceGetHeight(surface);
  2511 + OSType format_type = CVPixelBufferGetPixelFormatType(cvBufferRef);
  2512 +
  2513 + glEnable(GL_TEXTURE_RECTANGLE_ARB);
  2514 + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, plane.id);
  2515 + if (format_type == kCVPixelFormatType_422YpCbCr8)
  2516 + CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_ARB, GL_RGB8,
  2517 + texWidth, texHeight, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, surface, 0);
  2518 + else if (format_type == kCVPixelFormatType_32BGRA)
  2519 + CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA8,
  2520 + texWidth, texHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface, 0);
  2521 + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
  2522 + glDisable(GL_TEXTURE_RECTANGLE_ARB);
  2523 +#endif
  2524 +
  2525 + CVBufferRelease(cvBufferRef);
  2526 + m_buffers[index].cvBufferRef = NULL;
  2527 +
  2528 + // Calculate Texture Source Rects
  2529 + plane.rect = m_sourceRect;
  2530 + plane.width = m_buffers[index].image.width;
  2531 + plane.height = m_buffers[index].image.height;
  2532 + plane.flipindex = m_buffers[index].flipindex;
  2533 + }
  2534 +
  2535 + m_eventTexturesDone[index]->Set();
  2536 +#endif
  2537 +}
  2538 +
  2539 +void CLinuxRendererGL::DeleteCVRefTexture(int index)
  2540 +{
  2541 +#ifdef TARGET_DARWIN
  2542 + YUVPLANE &plane = m_buffers[index].fields[0][0];
  2543 +
  2544 + if (m_buffers[index].cvBufferRef)
  2545 + CVBufferRelease(m_buffers[index].cvBufferRef);
  2546 + m_buffers[index].cvBufferRef = NULL;
  2547 +
  2548 + if (plane.id && glIsTexture(plane.id))
  2549 + glDeleteTextures(1, &plane.id), plane.id = 0;
  2550 +#endif
  2551 +}
  2552 +
  2553 +bool CLinuxRendererGL::CreateCVRefTexture(int index)
  2554 +{
  2555 +#ifdef TARGET_DARWIN
  2556 + YV12Image &im = m_buffers[index].image;
  2557 + YUVFIELDS &fields = m_buffers[index].fields;
  2558 + YUVPLANE &plane = fields[0][0];
  2559 +
  2560 + DeleteCVRefTexture(index);
  2561 +
  2562 + memset(&im , 0, sizeof(im));
  2563 + memset(&fields, 0, sizeof(fields));
  2564 +
  2565 + im.height = m_sourceHeight;
  2566 + im.width = m_sourceWidth;
  2567 +
  2568 + plane.texwidth = im.width;
  2569 + plane.texheight = im.height;
  2570 + plane.pixpertex_x = 1;
  2571 + plane.pixpertex_y = 1;
  2572 +
  2573 + if(m_renderMethod & RENDER_POT)
  2574 + {
  2575 + plane.texwidth = NP2(plane.texwidth);
  2576 + plane.texheight = NP2(plane.texheight);
  2577 + }
  2578 + glEnable(GL_TEXTURE_RECTANGLE_ARB);
  2579 + glGenTextures(1, &plane.id);
  2580 +
  2581 +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
  2582 + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, plane.id);
  2583 + // Set storage hint. Can also use GL_STORAGE_SHARED_APPLE see docs.
  2584 + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_CACHED_APPLE);
  2585 + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  2586 + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  2587 + // This is necessary for non-power-of-two textures
  2588 + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  2589 + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  2590 + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, plane.texwidth, plane.texheight, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE, NULL);
  2591 + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
  2592 +#endif
  2593 + glDisable(GL_TEXTURE_RECTANGLE_ARB);
  2594 +
  2595 + m_eventTexturesDone[index]->Set();
  2596 +#endif
  2597 + return true;
  2598 +}
  2599 +
2403 2600 void CLinuxRendererGL::UploadYUV422PackedTexture(int source)
2404 2601 {
2405 2602 YUVBUFFER& buf = m_buffers[source];
@@ -3201,4 +3398,16 @@ void CLinuxRendererGL::AddProcessor(VAAPI::CHolder& holder)
3201 3398 }
3202 3399 #endif
3203 3400
  3401 +#ifdef TARGET_DARWIN
  3402 +void CLinuxRendererGL::AddProcessor(struct __CVBuffer *cvBufferRef)
  3403 +{
  3404 + YUVBUFFER &buf = m_buffers[NextYV12Texture()];
  3405 + if (buf.cvBufferRef)
  3406 + CVBufferRelease(buf.cvBufferRef);
  3407 + buf.cvBufferRef = cvBufferRef;
  3408 + // retain another reference, this way dvdplayer and renderer can issue releases.
  3409 + CVBufferRetain(buf.cvBufferRef);
  3410 +}
  3411 +#endif
  3412 +
3204 3413 #endif
12 xbmc/cores/VideoRenderers/LinuxRendererGL.h
@@ -91,6 +91,7 @@ enum RenderMethod
91 91 RENDER_VDPAU=0x08,
92 92 RENDER_POT=0x10,
93 93 RENDER_VAAPI=0x20,
  94 + RENDER_CVREF = 0x40,
94 95 };
95 96
96 97 enum RenderQuality
@@ -145,6 +146,9 @@ class CLinuxRendererGL : public CBaseRenderer
145 146 #ifdef HAVE_LIBVA
146 147 virtual void AddProcessor(VAAPI::CHolder& holder);
147 148 #endif
  149 +#ifdef TARGET_DARWIN
  150 + virtual void AddProcessor(struct __CVBuffer *cvBufferRef);
  151 +#endif
148 152
149 153 virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255);
150 154
@@ -193,6 +197,10 @@ class CLinuxRendererGL : public CBaseRenderer
193 197 void DeleteVAAPITexture(int index);
194 198 bool CreateVAAPITexture(int index);
195 199
  200 + void UploadCVRefTexture(int index);
  201 + void DeleteCVRefTexture(int index);
  202 + bool CreateCVRefTexture(int index);
  203 +
196 204 void UploadYUV422PackedTexture(int index);
197 205 void DeleteYUV422PackedTexture(int index);
198 206 bool CreateYUV422PackedTexture(int index);
@@ -210,6 +218,7 @@ class CLinuxRendererGL : public CBaseRenderer
210 218 void RenderSoftware(int renderBuffer, int field); // single pass s/w yuv2rgb renderer
211 219 void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware
212 220 void RenderVAAPI(int renderBuffer, int field); // render using vdpau hardware
  221 + void RenderCoreVideoRef(int renderBuffer, int field);// CoreVideo reference
213 222
214 223 CFrameBufferObject m_fbo;
215 224
@@ -271,6 +280,9 @@ class CLinuxRendererGL : public CBaseRenderer
271 280 #ifdef HAVE_LIBVA
272 281 VAAPI::CHolder& vaapi;
273 282 #endif
  283 +#ifdef TARGET_DARWIN_OSX
  284 + struct __CVBuffer *cvBufferRef;
  285 +#endif
274 286 };
275 287
276 288 typedef YUVBUFFER YUVBUFFERS[NUM_BUFFERS];
2  xbmc/cores/VideoRenderers/RenderManager.cpp
@@ -840,7 +840,7 @@ int CXBMCRenderManager::AddVideoPicture(DVDVideoPicture& pic)
840 840 else if(pic.format == RENDER_FMT_OMXEGL)
841 841 m_pRenderer->AddProcessor(pic.openMax, &pic);
842 842 #endif
843   -#ifdef HAVE_VIDEOTOOLBOXDECODER
  843 +#ifdef TARGET_DARWIN
844 844 else if(pic.format == RENDER_FMT_CVBREF)
845 845 m_pRenderer->AddProcessor(pic.cvBufferRef);
846 846 #endif
200 xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.cpp
@@ -87,6 +87,7 @@ enum {
87 87 kCVPixelFormatType_422YpCbCr8 = FourCharCode('2vuy'),
88 88 kCVPixelFormatType_32BGRA = FourCharCode('BGRA')
89 89 };
  90 +const CFStringRef kCVPixelBufferIOSurfacePropertiesKey = CFSTR("IOSurfaceProperties");
90 91 #endif
91 92
92 93 ////////////////////////////////////////////////////////////////////////////////////////////
@@ -640,8 +641,6 @@ CDVDVideoCodecVDA::CDVDVideoCodecVDA() : CDVDVideoCodec()
640 641 m_convert_3byteTo4byteNALSize = false;
641 642 m_dllAvUtil = NULL;
642 643 m_dllAvFormat = NULL;
643   - m_dllSwScale = NULL;
644   - memset(&m_videobuffer, 0, sizeof(DVDVideoPicture));
645 644 }
646 645
647 646 CDVDVideoCodecVDA::~CDVDVideoCodecVDA()
@@ -803,14 +802,6 @@ bool CDVDVideoCodecVDA::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
803 802 return false;
804 803 }
805 804
806   - // input stream is qualified, now we can load dlls.
807   - m_dllSwScale = new DllSwScale;
808   - if (!m_dllSwScale->Load())
809   - {
810   - CFRelease(avcCData);
811   - return false;
812   - }
813   -
814 805 // setup the decoder configuration dict
815 806 CFMutableDictionaryRef decoderConfiguration = CFDictionaryCreateMutable(
816 807 kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
@@ -832,20 +823,28 @@ bool CDVDVideoCodecVDA::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
832 823
833 824 // setup the destination image buffer dict, vda will output this pict format
834 825 CFMutableDictionaryRef destinationImageBufferAttributes = CFDictionaryCreateMutable(
835   - kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
836   -
  826 + kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
837 827 OSType cvPixelFormatType = kCVPixelFormatType_422YpCbCr8;
838 828 CFNumberRef pixelFormat = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &cvPixelFormatType);
839   - CFDictionarySetValue(destinationImageBufferAttributes, kCVPixelBufferPixelFormatTypeKey, pixelFormat);
840   - // release the retained object refs, destinationImageBufferAttributes owns it now
  829 +
  830 + // an IOSurface properties dictionary
  831 + CFDictionaryRef iosurfaceDictionary = CFDictionaryCreate(kCFAllocatorDefault,
  832 + NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
  833 +
  834 + CFDictionarySetValue(destinationImageBufferAttributes,
  835 + kCVPixelBufferPixelFormatTypeKey, pixelFormat);
  836 + CFDictionarySetValue(destinationImageBufferAttributes,
  837 + kCVPixelBufferIOSurfacePropertiesKey, iosurfaceDictionary);
  838 + // release the retained object refs, destinationImageBufferAttributes owns them now
841 839 CFRelease(pixelFormat);
  840 + CFRelease(iosurfaceDictionary);
842 841
843 842 // create the VDADecoder object
844 843 OSStatus status;
845 844 try
846 845 {
847 846 status = m_dll->VDADecoderCreate(decoderConfiguration, destinationImageBufferAttributes,
848   - (VDADecoderOutputCallback *)VDADecoderCallback, this, (VDADecoder*)&m_vda_decoder);
  847 + (VDADecoderOutputCallback*)VDADecoderCallback, this, (VDADecoder*)&m_vda_decoder);
849 848 }
850 849 catch (...)
851 850 {
@@ -856,46 +855,15 @@ bool CDVDVideoCodecVDA::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
856 855 CFRelease(destinationImageBufferAttributes);
857 856 if (status != kVDADecoderNoErr)
858 857 {
859   - if (status == kVDADecoderDecoderFailedErr)
860   - CLog::Log(LOGNOTICE, "%s - VDADecoder Codec failed to open, currently in use by another process",
861   - __FUNCTION__);
862   - else
863   - CLog::Log(LOGNOTICE, "%s - VDADecoder Codec failed to open, status(%d), profile(%d), level(%d)",
864   - __FUNCTION__, (int)status, profile, level);
  858 + if (status == kVDADecoderDecoderFailedErr)
  859 + CLog::Log(LOGNOTICE, "%s - VDADecoder Codec failed to open, currently in use by another process",
  860 + __FUNCTION__);
  861 + else
  862 + CLog::Log(LOGNOTICE, "%s - VDADecoder Codec failed to open, status(%d), profile(%d), level(%d)",
  863 + __FUNCTION__, (int)status, profile, level);
865 864 return false;
866 865 }
867 866
868   - // allocate a YV12 DVDVideoPicture buffer.
869   - // first make sure all properties are reset.
870   - memset(&m_videobuffer, 0, sizeof(DVDVideoPicture));
871   - unsigned int iPixels = width * height;
872   - unsigned int iChromaPixels = iPixels/4;
873   -
874   - m_videobuffer.pts = DVD_NOPTS_VALUE;
875   - m_videobuffer.iFlags = DVP_FLAG_ALLOCATED;
876   - m_videobuffer.format = RENDER_FMT_YUV420P;
877   - m_videobuffer.color_range = 0;
878   - m_videobuffer.color_matrix = 4;
879   - m_videobuffer.iWidth = width;
880   - m_videobuffer.iHeight = height;
881   - m_videobuffer.iDisplayWidth = width;
882   - m_videobuffer.iDisplayHeight = height;
883   -
884   - m_videobuffer.iLineSize[0] = width; //Y
885   - m_videobuffer.iLineSize[1] = width/2; //U
886   - m_videobuffer.iLineSize[2] = width/2; //V
887   - m_videobuffer.iLineSize[3] = 0;
888   -
889   - m_videobuffer.data[0] = (BYTE*)malloc(iPixels); //Y
890   - m_videobuffer.data[1] = (BYTE*)malloc(iChromaPixels); //U
891   - m_videobuffer.data[2] = (BYTE*)malloc(iChromaPixels); //V
892   - m_videobuffer.data[3] = NULL;
893   -
894   - // set all data to 0 for less artifacts.. hmm.. what is black in YUV??
895   - memset(m_videobuffer.data[0], 0, iPixels);
896   - memset(m_videobuffer.data[1], 0, iChromaPixels);
897   - memset(m_videobuffer.data[2], 0, iChromaPixels);
898   -
899 867 m_DropPictures = false;
900 868 m_max_ref_frames = std::min(m_max_ref_frames, 5);
901 869 m_sort_time_offset = (CurrentHostCounter() * 1000.0) / CurrentHostFrequency();
@@ -910,32 +878,13 @@ void CDVDVideoCodecVDA::Dispose()
910 878 {
911 879 CCocoaAutoPool pool;
912 880 if (m_vda_decoder)
913   - {
914   - m_dll->VDADecoderDestroy((VDADecoder)m_vda_decoder);
915   - m_vda_decoder = NULL;
916   - }
917   - if (m_videobuffer.iFlags & DVP_FLAG_ALLOCATED)
918   - {
919   - free(m_videobuffer.data[0]);
920   - free(m_videobuffer.data[1]);
921   - free(m_videobuffer.data[2]);
922   - m_videobuffer.iFlags = 0;
923   - }
  881 + m_dll->VDADecoderDestroy((VDADecoder)m_vda_decoder), m_vda_decoder = NULL;
  882 +
924 883 if (m_dllAvUtil)
925   - {
926   - delete m_dllAvUtil;
927   - m_dllAvUtil = NULL;
928   - }
  884 + delete m_dllAvUtil, m_dllAvUtil = NULL;
  885 +
929 886 if (m_dllAvFormat)
930   - {
931   - delete m_dllAvFormat;
932   - m_dllAvFormat = NULL;
933   - }
934   - if (m_dllSwScale)
935   - {
936   - delete m_dllSwScale;
937   - m_dllSwScale = NULL;
938   - }
  887 + delete m_dllAvFormat, m_dllAvFormat = NULL;
939 888 }
940 889
941 890 void CDVDVideoCodecVDA::SetDropState(bool bDrop)
@@ -1016,9 +965,7 @@ int CDVDVideoCodecVDA::Decode(BYTE* pData, int iSize, double dts, double pts)
1016 965 }
1017 966
1018 967 if (m_queue_depth < m_max_ref_frames)
1019   - {
1020 968 return VC_BUFFER;
1021   - }
1022 969
1023 970 return VC_PICTURE | VC_BUFFER;
1024 971 }
@@ -1036,86 +983,42 @@ void CDVDVideoCodecVDA::Reset(void)
1036 983
1037 984 bool CDVDVideoCodecVDA::GetPicture(DVDVideoPicture* pDvdVideoPicture)
1038 985 {
1039   - CCocoaAutoPool pool;
1040   - FourCharCode pixel_buffer_format;
1041   - CVPixelBufferRef picture_buffer_ref;
1042   -
1043   - // clone the video picture buffer settings.
1044   - *pDvdVideoPicture = m_videobuffer;
1045   -
1046 986 // get the top yuv frame, we risk getting the wrong frame if the frame queue
1047 987 // depth is less than the number of encoded reference frames. If queue depth
1048 988 // is greater than the number of encoded reference frames, then the top frame
1049   - // will never change and we can just grab a ref to the top frame. This way
1050   - // we don't lockout the vdadecoder while doing color format convert.
  989 + // will never change and we can just grab a ref to the top frame.
1051 990 pthread_mutex_lock(&m_queue_mutex);
1052   - picture_buffer_ref = m_display_queue->pixel_buffer_ref;
1053   - pixel_buffer_format = m_display_queue->pixel_buffer_format;
1054   - pDvdVideoPicture->dts = m_display_queue->dts;
1055   - pDvdVideoPicture->pts = m_display_queue->pts;
  991 + pDvdVideoPicture->dts = m_display_queue->dts;
  992 + pDvdVideoPicture->pts = m_display_queue->pts;
  993 + pDvdVideoPicture->cvBufferRef = m_display_queue->pixel_buffer_ref;
  994 + m_display_queue->pixel_buffer_ref = NULL;
1056 995 pthread_mutex_unlock(&m_queue_mutex);
1057 996
1058   - // lock the CVPixelBuffer down
1059   - CVPixelBufferLockBaseAddress(picture_buffer_ref, 0);
1060   - int row_stride = CVPixelBufferGetBytesPerRowOfPlane(picture_buffer_ref, 0);
1061   - uint8_t *base_ptr = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(picture_buffer_ref, 0);
1062   - if (base_ptr)
1063   - {
1064   - if (pixel_buffer_format == kCVPixelFormatType_422YpCbCr8)
1065   - UYVY422_to_YUV420P(base_ptr, row_stride, pDvdVideoPicture);
1066   - else if (pixel_buffer_format == kCVPixelFormatType_32BGRA)
1067   - BGRA_to_YUV420P(base_ptr, row_stride, pDvdVideoPicture);
1068   - }
1069   - // unlock the CVPixelBuffer
1070   - CVPixelBufferUnlockBaseAddress(picture_buffer_ref, 0);
  997 + pDvdVideoPicture->format = RENDER_FMT_CVBREF;
  998 + pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
  999 + pDvdVideoPicture->color_range = 0;
  1000 + pDvdVideoPicture->color_matrix = 4;
  1001 + pDvdVideoPicture->iWidth = CVPixelBufferGetWidth(pDvdVideoPicture->cvBufferRef);
  1002 + pDvdVideoPicture->iHeight = CVPixelBufferGetHeight(pDvdVideoPicture->cvBufferRef);
  1003 + pDvdVideoPicture->iDisplayWidth = pDvdVideoPicture->iWidth;
  1004 + pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight;
1071 1005
1072 1006 // now we can pop the top frame.
1073 1007 DisplayQueuePop();
1074   -
1075 1008 //CLog::Log(LOGNOTICE, "%s - VDADecoderDecode dts(%f), pts(%f)", __FUNCTION__,
1076 1009 // pDvdVideoPicture->dts, pDvdVideoPicture->pts);
1077 1010
1078 1011 return VC_PICTURE | VC_BUFFER;
1079 1012 }
1080 1013
1081   -void CDVDVideoCodecVDA::UYVY422_to_YUV420P(uint8_t *yuv422_ptr, int yuv422_stride, DVDVideoPicture *picture)
  1014 +bool CDVDVideoCodecVDA::ClearPicture(DVDVideoPicture* pDvdVideoPicture)
1082 1015 {
1083   - // convert PIX_FMT_UYVY422 to PIX_FMT_YUV420P.
1084   - struct SwsContext *swcontext = m_dllSwScale->sws_getContext(
1085   - m_videobuffer.iWidth, m_videobuffer.iHeight, PIX_FMT_UYVY422,
1086   - m_videobuffer.iWidth, m_videobuffer.iHeight, PIX_FMT_YUV420P,
1087   - SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL);
1088   - if (swcontext)
1089   - {
1090   - uint8_t *src[] = { yuv422_ptr, 0, 0, 0 };
1091   - int srcStride[] = { yuv422_stride, 0, 0, 0 };
  1016 + // release any previous retained image buffer ref that
  1017 + // has not been passed up to renderer (ie. dropped frames, etc).
  1018 + if (pDvdVideoPicture->cvBufferRef)
  1019 + CVBufferRelease(pDvdVideoPicture->cvBufferRef);
1092 1020
1093   - uint8_t *dst[] = { picture->data[0], picture->data[1], picture->data[2], 0 };
1094   - int dstStride[] = { picture->iLineSize[0], picture->iLineSize[1], picture->iLineSize[2], 0 };
1095   -
1096   - m_dllSwScale->sws_scale(swcontext, src, srcStride, 0, picture->iHeight, dst, dstStride);
1097   - m_dllSwScale->sws_freeContext(swcontext);
1098   - }
1099   -}
1100   -
1101   -void CDVDVideoCodecVDA::BGRA_to_YUV420P(uint8_t *bgra_ptr, int bgra_stride, DVDVideoPicture *picture)
1102   -{
1103   - // convert PIX_FMT_BGRA to PIX_FMT_YUV420P.
1104   - struct SwsContext *swcontext = m_dllSwScale->sws_getContext(
1105   - m_videobuffer.iWidth, m_videobuffer.iHeight, PIX_FMT_BGRA,
1106   - m_videobuffer.iWidth, m_videobuffer.iHeight, PIX_FMT_YUV420P,
1107   - SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL);
1108   - if (swcontext)
1109   - {
1110   - uint8_t *src[] = { bgra_ptr, 0, 0, 0 };
1111   - int srcStride[] = { bgra_stride, 0, 0, 0 };
1112   -
1113   - uint8_t *dst[] = { picture->data[0], picture->data[1], picture->data[2], 0 };
1114   - int dstStride[] = { picture->iLineSize[0], picture->iLineSize[1], picture->iLineSize[2], 0 };
1115   -
1116   - m_dllSwScale->sws_scale(swcontext, src, srcStride, 0, picture->iHeight, dst, dstStride);
1117   - m_dllSwScale->sws_freeContext(swcontext);
1118   - }
  1021 + return CDVDVideoCodec::ClearPicture(pDvdVideoPicture);
1119 1022 }
1120 1023
1121 1024 void CDVDVideoCodecVDA::DisplayQueuePop(void)
@@ -1132,16 +1035,17 @@ void CDVDVideoCodecVDA::DisplayQueuePop(void)
1132 1035 pthread_mutex_unlock(&m_queue_mutex);
1133 1036
1134 1037 // and release it
1135   - CVPixelBufferRelease(top_frame->pixel_buffer_ref);
  1038 + if (top_frame->pixel_buffer_ref)
  1039 + CVBufferRelease(top_frame->pixel_buffer_ref);
1136 1040 free(top_frame);
1137 1041 }
1138 1042
1139 1043 void CDVDVideoCodecVDA::VDADecoderCallback(
1140   - void *decompressionOutputRefCon,
1141   - CFDictionaryRef frameInfo,
1142   - OSStatus status,
1143   - uint32_t infoFlags,
1144   - CVImageBufferRef imageBuffer)
  1044 + void *decompressionOutputRefCon,
  1045 + CFDictionaryRef frameInfo,
  1046 + OSStatus status,
  1047 + uint32_t infoFlags,
  1048 + CVImageBufferRef imageBuffer)
1145 1049 {
1146 1050 CCocoaAutoPool pool;
1147 1051 // Warning, this is an async callback. There can be multiple frames in flight.
@@ -1172,7 +1076,7 @@ void CDVDVideoCodecVDA::VDADecoderCallback(
1172 1076 frame_queue *newFrame = (frame_queue*)calloc(sizeof(frame_queue), 1);
1173 1077 newFrame->nextframe = NULL;
1174 1078 newFrame->pixel_buffer_format = format_type;
1175   - newFrame->pixel_buffer_ref = CVPixelBufferRetain(imageBuffer);
  1079 + newFrame->pixel_buffer_ref = CVBufferRetain(imageBuffer);
1176 1080 GetFrameDisplayTimeFromDictionary(frameInfo, newFrame);
1177 1081
1178 1082 // if both dts or pts are good we use those, else use decoder insert time for frame sort
8 xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVDA.h
@@ -31,7 +31,7 @@ typedef struct frame_queue {
31 31 double pts;
32 32 double sort_time;
33 33 FourCharCode pixel_buffer_format;
34   - CVPixelBufferRef pixel_buffer_ref;
  34 + CVBufferRef pixel_buffer_ref;
35 35 struct frame_queue *nextframe;
36 36 } frame_queue;
37 37
@@ -51,13 +51,12 @@ class CDVDVideoCodecVDA : public CDVDVideoCodec
51 51 virtual int Decode(BYTE *pData, int iSize, double dts, double pts);
52 52 virtual void Reset(void);
53 53 virtual bool GetPicture(DVDVideoPicture *pDvdVideoPicture);
  54 + virtual bool ClearPicture(DVDVideoPicture* pDvdVideoPicture);
54 55 virtual void SetDropState(bool bDrop);
55 56 virtual const char* GetName(void) { return (const char*)m_pFormatName; }
56 57
57 58 protected:
58 59 void DisplayQueuePop(void);
59   - void UYVY422_to_YUV420P(uint8_t *yuv422_ptr, int yuv422_stride, DVDVideoPicture *picture);
60   - void BGRA_to_YUV420P(uint8_t *bgra_ptr, int bgra_stride, DVDVideoPicture *picture);
61 60
62 61 static void VDADecoderCallback(
63 62 void *decompressionOutputRefCon, CFDictionaryRef frameInfo,
@@ -79,9 +78,6 @@ class CDVDVideoCodecVDA : public CDVDVideoCodec
79 78 bool m_convert_3byteTo4byteNALSize;
80 79 DllAvUtil *m_dllAvUtil;
81 80 DllAvFormat *m_dllAvFormat;
82   -
83   - DllSwScale *m_dllSwScale;
84   - DVDVideoPicture m_videobuffer;
85 81 };
86 82
87 83 #endif
3  xbmc/windowing/osx/WinSystemOSX.h
@@ -63,6 +63,9 @@ class CWinSystemOSX : public CWinSystemBase
63 63 virtual int GetNumScreens();
64 64
65 65 void CheckDisplayChanging(u_int32_t flags);
  66 +
  67 + void* GetCGLContextObj();
  68 +
66 69 protected:
67 70 void* CreateWindowedContext(void* shareCtx);
68 71 void* CreateFullScreenContext(int screen_index, void* shareCtx);
5 xbmc/windowing/osx/WinSystemOSX.mm
@@ -1398,4 +1398,9 @@ static void DisplayReconfigured(CGDirectDisplayID display,
1398 1398 }
1399 1399 }
1400 1400
  1401 +void* CWinSystemOSX::GetCGLContextObj()
  1402 +{
  1403 + return [(NSOpenGLContext*)m_glContext CGLContextObj];
  1404 +}
  1405 +
1401 1406 #endif

0 comments on commit 1e94198

bobo1on1

That c/p'd comment is not relevant here ;)

bobo1on1

We use GL_MODULATE instead of GL_REPLACE for blending to work correctly, are you sure this is ok?

Please sign in to comment.
Something went wrong with that request. Please try again.