aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoakim Plate <elupus@ecce.se>2013-06-08 11:52:10 +0200
committerJoakim Plate <elupus@ecce.se>2013-06-08 11:52:10 +0200
commitd192ca3dc7122148d03292ff1ed37fc2fa2225b7 (patch)
treefffe1ef2b0be9030e5c7800676458fcdc1805eda
parent13a3215aed9b9d9d4a068a5da35ef376dcc0dc39 (diff)
dvdplayer: support vda decoding using ffmpeg hwaccel infrastructure
This removes the requirment that width/height have to be known before hand, as well as avoid need to extract extradata before hand.
-rw-r--r--XBMC.xcodeproj/project.pbxproj6
-rw-r--r--configure.in2
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp17
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp273
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h54
5 files changed, 351 insertions, 1 deletions
diff --git a/XBMC.xcodeproj/project.pbxproj b/XBMC.xcodeproj/project.pbxproj
index d46800d3e5..4eda502c5b 100644
--- a/XBMC.xcodeproj/project.pbxproj
+++ b/XBMC.xcodeproj/project.pbxproj
@@ -234,6 +234,7 @@
43BF09A21080D1E900E25290 /* AVTransportSCPD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43BF099E1080D1E900E25290 /* AVTransportSCPD.cpp */; settings = {COMPILER_FLAGS = "-I$SRCROOT/lib/libUPnP/Platinum/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Platinum -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaConnect -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaRenderer -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaServer -I$SRCROOT/lib/libUPnP/Platinum/Source/Extras -I$SRCROOT/lib/libUPnP/Neptune/Source/System/Posix -I$SRCROOT/lib/libUPnP/Neptune/Source/Core"; }; };
43BF09A31080D1E900E25290 /* RenderingControlSCPD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43BF099F1080D1E900E25290 /* RenderingControlSCPD.cpp */; settings = {COMPILER_FLAGS = "-I$SRCROOT/lib/libUPnP/Platinum/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Platinum -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaConnect -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaRenderer -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaServer -I$SRCROOT/lib/libUPnP/Platinum/Source/Extras -I$SRCROOT/lib/libUPnP/Neptune/Source/System/Posix -I$SRCROOT/lib/libUPnP/Neptune/Source/Core"; }; };
43BF09AB1080D2ED00E25290 /* RdrConnectionManagerSCPD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43BF09A81080D2ED00E25290 /* RdrConnectionManagerSCPD.cpp */; settings = {COMPILER_FLAGS = "-I$SRCROOT/lib/libUPnP/Platinum/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Platinum -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaConnect -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaRenderer -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaServer -I$SRCROOT/lib/libUPnP/Platinum/Source/Extras -I$SRCROOT/lib/libUPnP/Neptune/Source/System/Posix -I$SRCROOT/lib/libUPnP/Neptune/Source/Core"; }; };
+ 551C3A45175A12010051AAAD /* VDA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 551C3A43175A12010051AAAD /* VDA.cpp */; };
552840CC1626163B00ED1333 /* UPnPPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 552840CA1626163B00ED1333 /* UPnPPlayer.cpp */; settings = {COMPILER_FLAGS = "-I$SRCROOT/lib/libUPnP/Platinum/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Platinum -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaConnect -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaRenderer -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaServer -I$SRCROOT/lib/libUPnP/Platinum/Source/Extras -I$SRCROOT/lib/libUPnP/Neptune/Source/System/Posix -I$SRCROOT/lib/libUPnP/Neptune/Source/Core"; }; };
552A226915F7E14B0015C0D0 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 552A226815F7E14B0015C0D0 /* main.cpp */; };
553840F215F360B400CE061B /* PltMimeType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 553840ED15F360B400CE061B /* PltMimeType.cpp */; settings = {COMPILER_FLAGS = "-I$SRCROOT/lib/libUPnP/Platinum/Source/Core -I$SRCROOT/lib/libUPnP/Platinum/Source/Platinum -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaConnect -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaRenderer -I$SRCROOT/lib/libUPnP/Platinum/Source/Devices/MediaServer -I$SRCROOT/lib/libUPnP/Platinum/Source/Extras -I$SRCROOT/lib/libUPnP/Neptune/Source/System/Posix -I$SRCROOT/lib/libUPnP/Neptune/Source/Core"; }; };
@@ -3603,6 +3604,8 @@
43BF09A91080D2ED00E25290 /* RenderingControlSCPD_Full.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = RenderingControlSCPD_Full.xml; sourceTree = "<group>"; };
43BF09DD1080D39300E25290 /* fastmemcpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fastmemcpy.h; sourceTree = "<group>"; };
43FAC87112D6349400F67914 /* IStorageProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IStorageProvider.h; sourceTree = "<group>"; };
+ 551C3A43175A12010051AAAD /* VDA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VDA.cpp; sourceTree = "<group>"; };
+ 551C3A44175A12010051AAAD /* VDA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VDA.h; sourceTree = "<group>"; };
552840CA1626163B00ED1333 /* UPnPPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UPnPPlayer.cpp; sourceTree = "<group>"; };
552840CB1626163B00ED1333 /* UPnPPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPnPPlayer.h; sourceTree = "<group>"; };
552A226815F7E14B0015C0D0 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = main/main.cpp; sourceTree = "<group>"; };
@@ -7430,6 +7433,8 @@
E4991590174E6ABE00741B6D /* DVDVideoCodecVideoToolBox.h */,
E38E15410D25F9F900618676 /* DVDVideoPPFFmpeg.cpp */,
E38E15420D25F9F900618676 /* DVDVideoPPFFmpeg.h */,
+ 551C3A43175A12010051AAAD /* VDA.cpp */,
+ 551C3A44175A12010051AAAD /* VDA.h */,
);
path = Video;
sourceTree = "<group>";
@@ -10512,6 +10517,7 @@
DF529BAE1741697B00523FB4 /* Environment.cpp in Sources */,
DFE4095B17417FDF00473BD9 /* LegacyPathTranslation.cpp in Sources */,
0E3036EC1760F68A00D93596 /* FavouritesDirectory.cpp in Sources */,
+ 551C3A45175A12010051AAAD /* VDA.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/configure.in b/configure.in
index e5ae8d478b..72cfc71da9 100644
--- a/configure.in
+++ b/configure.in
@@ -2553,7 +2553,7 @@ XB_CONFIG_MODULE([lib/ffmpeg], [
ffmpg_config="$ffmpg_config --disable-devices --disable-doc"
ffmpg_config="$ffmpg_config --disable-ffplay --disable-ffmpeg"
ffmpg_config="$ffmpg_config --disable-ffprobe --disable-ffserver"
- ffmpg_config="$ffmpg_config --disable-vda --disable-crystalhd"
+ ffmpg_config="$ffmpg_config --enable-vda --disable-crystalhd"
ffmpg_config="$ffmpg_config --disable-decoder=mpeg_xvmc"
# handle conditional enables/disables
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
index 310ee55ba6..e76feb3e0c 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
@@ -57,6 +57,9 @@
#ifdef HAVE_LIBVA
#include "VAAPI.h"
#endif
+#ifdef TARGET_DARWIN_OSX
+#include "VDA.h"
+#endif
using namespace boost;
@@ -118,6 +121,20 @@ enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx
dec->Release();
}
#endif
+
+#ifdef TARGET_DARWIN_OSX
+ if (*cur == AV_PIX_FMT_VDA_VLD && CSettings::Get().GetBool("videoplayer.usevda"))
+ {
+ VDA::CDecoder* dec = new VDA::CDecoder();
+ if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
+ {
+ ctx->SetHardware(dec);
+ return *cur;
+ }
+ else
+ dec->Release();
+ }
+#endif
cur++;
}
return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt);
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp
new file mode 100644
index 0000000000..d6864cb2ff
--- /dev/null
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.cpp
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include "system.h"
+#ifdef TARGET_DARWIN_OSX
+#include "osx/CocoaInterface.h"
+#include "DVDVideoCodec.h"
+#include "DVDCodecs/DVDCodecUtils.h"
+#include "VDA.h"
+
+extern "C" {
+ #include <libavcodec/vda.h>
+}
+
+using namespace std;
+using namespace VDA;
+
+
+static void RelBufferS(AVCodecContext *avctx, AVFrame *pic)
+{ ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->RelBuffer(avctx, pic); }
+
+static int GetBufferS(AVCodecContext *avctx, AVFrame *pic)
+{ return ((CDecoder*)((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetHardware())->GetBuffer(avctx, pic); }
+
+CDecoder::CDecoder()
+: m_renderbuffers_count(0)
+{
+ m_ctx = (vda_context*)calloc(1, sizeof(vda_context));
+}
+
+CDecoder::~CDecoder()
+{
+ Close();
+ free(m_ctx);
+}
+
+void CDecoder::RelBuffer(AVCodecContext *avctx, AVFrame *pic)
+{
+ CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3];
+ CVPixelBufferRelease(cv_buffer);
+
+ for (int i = 0; i < 4; i++)
+ pic->data[i] = NULL;
+}
+
+int CDecoder::GetBuffer(AVCodecContext *avctx, AVFrame *pic)
+{
+ pic->type = FF_BUFFER_TYPE_USER;
+ pic->data[0] = (uint8_t *)1;
+ return 0;
+}
+
+static void vda_decoder_callback (void *vda_hw_ctx,
+ CFDictionaryRef user_info,
+ OSStatus status,
+ uint32_t infoFlags,
+ CVImageBufferRef image_buffer)
+{
+ struct vda_context *vda_ctx = (struct vda_context *)vda_hw_ctx;
+
+ if (!image_buffer)
+ return;
+
+ if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer))
+ return;
+
+ vda_ctx->cv_buffer = CVPixelBufferRetain(image_buffer);
+}
+
+bool CDecoder::Create(AVCodecContext *avctx)
+{
+ OSStatus status;
+ CFNumberRef height;
+ CFNumberRef width;
+ CFNumberRef format;
+ CFDataRef avc_data;
+ CFMutableDictionaryRef config_info;
+ CFMutableDictionaryRef buffer_attributes;
+ CFMutableDictionaryRef io_surface_properties;
+ CFNumberRef cv_pix_fmt;
+
+ m_ctx->priv_bitstream = NULL;
+ m_ctx->priv_allocated_size = 0;
+
+ /* Each VCL NAL in the bitstream sent to the decoder
+ * is preceded by a 4 bytes length header.
+ * Change the avcC atom header if needed, to signal headers of 4 bytes. */
+ if (avctx->extradata_size >= 4 && (avctx->extradata[4] & 0x03) != 0x03) {
+ uint8_t *rw_extradata;
+
+ if (!(rw_extradata = (uint8_t*)av_malloc(avctx->extradata_size)))
+ return false;
+
+ memcpy(rw_extradata, avctx->extradata, avctx->extradata_size);
+
+ rw_extradata[4] |= 0x03;
+
+ avc_data = CFDataCreate(kCFAllocatorDefault, rw_extradata, avctx->extradata_size);
+
+ av_freep(&rw_extradata);
+ } else {
+ avc_data = CFDataCreate(kCFAllocatorDefault, avctx->extradata, avctx->extradata_size);
+ }
+
+ config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 4,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &m_ctx->height);
+ width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &m_ctx->width);
+ format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &m_ctx->format);
+
+ CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height , height);
+ CFDictionarySetValue(config_info, kVDADecoderConfiguration_Width , width);
+ CFDictionarySetValue(config_info, kVDADecoderConfiguration_SourceFormat, format);
+ CFDictionarySetValue(config_info, kVDADecoderConfiguration_avcCData , avc_data);
+
+ buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 2,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberSInt32Type,
+ &m_ctx->cv_pix_fmt_type);
+ CFDictionarySetValue(buffer_attributes,
+ kCVPixelBufferPixelFormatTypeKey,
+ cv_pix_fmt);
+ CFDictionarySetValue(buffer_attributes,
+ kCVPixelBufferIOSurfacePropertiesKey,
+ io_surface_properties);
+
+ status = VDADecoderCreate(config_info,
+ buffer_attributes,
+ (VDADecoderOutputCallback*)vda_decoder_callback,
+ m_ctx,
+ &m_ctx->decoder);
+
+ CFRelease(height);
+ CFRelease(width);
+ CFRelease(format);
+ CFRelease(avc_data);
+ CFRelease(config_info);
+ CFRelease(io_surface_properties);
+ CFRelease(cv_pix_fmt);
+ CFRelease(buffer_attributes);
+
+ if(status != kVDADecoderNoErr)
+ {
+ CLog::Log(LOGERROR, "VDA::CDecoder - Failed to init VDA decoder: %d", status);
+ return false;
+ }
+ return true;
+}
+
+void CDecoder::Close()
+{
+ OSStatus status = kVDADecoderNoErr;
+
+ if (m_ctx->decoder)
+ status = VDADecoderDestroy(m_ctx->decoder);
+ m_ctx->decoder = NULL;
+ av_freep(&m_ctx->priv_bitstream);
+}
+
+bool CDecoder::Open(AVCodecContext *avctx, enum PixelFormat fmt, unsigned int surfaces)
+{
+ Close();
+
+ if(fmt != AV_PIX_FMT_VDA_VLD)
+ return false;
+
+ if(avctx->codec_id != AV_CODEC_ID_H264)
+ return false;
+
+ switch(avctx->profile)
+ {
+ case FF_PROFILE_H264_HIGH_10:
+ case FF_PROFILE_H264_HIGH_10_INTRA:
+ case FF_PROFILE_H264_HIGH_422:
+ case FF_PROFILE_H264_HIGH_422_INTRA:
+ case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
+ case FF_PROFILE_H264_HIGH_444_INTRA:
+ case FF_PROFILE_H264_CAVLC_444:
+ return false;
+ default:
+ break;
+ }
+
+ if (Cocoa_GPUForDisplayIsNvidiaPureVideo3() && !CDVDCodecUtils::IsVP3CompatibleWidth(avctx->width))
+ {
+ CLog::Log(LOGNOTICE, "%s - Nvidia 9400 GPU hardware limitation, cannot decode a width of %d", __FUNCTION__, avctx->width);
+ return false;
+ }
+
+ if (avctx->profile == FF_PROFILE_H264_MAIN && avctx->level == 32 && avctx->refs > 4)
+ {
+ // Main@L3.2, VDA cannot handle greater than 4 reference frames
+ CLog::Log(LOGNOTICE, "%s - Main@L3.2 detected, VDA cannot decode.", __FUNCTION__);
+ return false;
+ }
+
+ /* init vda */
+ memset(m_ctx, 0, sizeof(struct vda_context));
+ m_ctx->width = avctx->width;
+ m_ctx->height = avctx->height;
+ m_ctx->format = 'avc1';
+ m_ctx->use_sync_decoding = 1;
+ m_ctx->cv_pix_fmt_type = kCVPixelFormatType_422YpCbCr8;
+
+ if (!Create(avctx))
+ return false;
+
+ avctx->pix_fmt = fmt;
+ avctx->hwaccel_context = m_ctx;
+ avctx->get_buffer = GetBufferS;
+ avctx->release_buffer = RelBufferS;
+
+ return true;
+}
+
+int CDecoder::Decode(AVCodecContext* avctx, AVFrame* frame)
+{
+ int status = Check(avctx);
+ if(status)
+ return status;
+
+ if(frame)
+ return VC_BUFFER | VC_PICTURE;
+ else
+ return VC_BUFFER;
+}
+
+bool CDecoder::GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture)
+{
+ ((CDVDVideoCodecFFmpeg*)avctx->opaque)->GetPictureCommon(picture);
+
+ picture->format = RENDER_FMT_CVBREF;
+ picture->cvBufferRef = (CVPixelBufferRef)frame->data[3];
+ return true;
+}
+
+int CDecoder::Check(AVCodecContext* avctx)
+{
+ return 0;
+}
+
+unsigned CDecoder::GetAllowedReferences()
+{
+ return m_renderbuffers_count;
+}
+
+#endif
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h
new file mode 100644
index 0000000000..154457f855
--- /dev/null
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/VDA.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#pragma once
+
+#include "system_gl.h"
+
+#include "DllAvCodec.h"
+#include "DVDVideoCodecFFmpeg.h"
+
+struct vda_context;
+
+namespace VDA {
+
+class CDecoder
+ : public CDVDVideoCodecFFmpeg::IHardwareDecoder
+{
+public:
+ CDecoder();
+ ~CDecoder();
+ virtual bool Open (AVCodecContext* avctx, const enum PixelFormat, unsigned int surfaces = 0);
+ virtual int Decode (AVCodecContext* avctx, AVFrame* frame);
+ virtual bool GetPicture(AVCodecContext* avctx, AVFrame* frame, DVDVideoPicture* picture);
+ virtual int Check (AVCodecContext* avctx);
+ virtual void Close();
+ virtual const std::string Name() { return "vda"; }
+ virtual CCriticalSection* Section() { return NULL; }
+ virtual unsigned GetAllowedReferences();
+
+ int GetBuffer(AVCodecContext *avctx, AVFrame *pic);
+ void RelBuffer(AVCodecContext *avctx, AVFrame *pic);
+protected:
+ bool Create(AVCodecContext* avctx);
+ unsigned m_renderbuffers_count;
+ vda_context* m_ctx;
+};
+
+}