summaryrefslogtreecommitdiffstats
path: root/tinyDAV/src/video/directx/tdav_producer_screencast_ddraw.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tinyDAV/src/video/directx/tdav_producer_screencast_ddraw.cxx')
-rwxr-xr-xtinyDAV/src/video/directx/tdav_producer_screencast_ddraw.cxx2018
1 files changed, 1006 insertions, 1012 deletions
diff --git a/tinyDAV/src/video/directx/tdav_producer_screencast_ddraw.cxx b/tinyDAV/src/video/directx/tdav_producer_screencast_ddraw.cxx
index 13507db..607b5ff 100755
--- a/tinyDAV/src/video/directx/tdav_producer_screencast_ddraw.cxx
+++ b/tinyDAV/src/video/directx/tdav_producer_screencast_ddraw.cxx
@@ -111,58 +111,57 @@
#define DDRAW_CHECK_HR(x) { HRESULT __hr__ = (x); if (FAILED(__hr__)) { DDRAW_DEBUG_ERROR("Operation Failed (%08x)", __hr__); goto bail; } }
typedef struct DDrawModule {
- LPDIRECTDRAW lpDD;
- HMODULE hDLL;
-}DDrawModule;
+ LPDIRECTDRAW lpDD;
+ HMODULE hDLL;
+} DDrawModule;
typedef struct DDrawModule FAR *LPDDrawModule;
#define DDrawModuleSafeFree(module) DDRAW_SAFE_RELEASE(&module.lpDD); if (module.hDLL) { FreeLibrary(module.hDLL), module.hDLL = NULL; }
-typedef struct tdav_producer_screencast_ddraw_s
-{
- TMEDIA_DECLARE_PRODUCER;
+typedef struct tdav_producer_screencast_ddraw_s {
+ TMEDIA_DECLARE_PRODUCER;
- HWND hwnd_preview;
- HWND hwnd_src;
+ HWND hwnd_preview;
+ HWND hwnd_src;
#if DDRAW_PREVIEW
- BITMAPINFO bi_preview;
+ BITMAPINFO bi_preview;
#endif /* DDRAW_PREVIEW */
#if DDRAW_CPU_MONITOR || DDRAW_CPU_THROTTLING
- tsk_timer_manager_handle_t *p_timer_mgr;
- struct {
- tsk_timer_id_t id_timer;
- int fps_target;
- } cpu;
+ tsk_timer_manager_handle_t *p_timer_mgr;
+ struct {
+ tsk_timer_id_t id_timer;
+ int fps_target;
+ } cpu;
#endif /* DDRAW_CPU_MONITOR || DDRAW_CPU_THROTTLING */
#if DDRAW_MT
- struct{
- tsk_thread_handle_t* tid[1];
- void* p_buff_yuv_aligned_array[DDRAW_MT_COUNT];
- BOOL b_flags_array[DDRAW_MT_COUNT];
- HANDLE h_events[DDRAW_MT_COUNT + 1]; // #DDRAW_MT_COUNT events for each buffer plus #1 for the shutdown/stop
- } mt;
+ struct {
+ tsk_thread_handle_t* tid[1];
+ void* p_buff_yuv_aligned_array[DDRAW_MT_COUNT];
+ BOOL b_flags_array[DDRAW_MT_COUNT];
+ HANDLE h_events[DDRAW_MT_COUNT + 1]; // #DDRAW_MT_COUNT events for each buffer plus #1 for the shutdown/stop
+ } mt;
#endif /* DDRAW_MT */
- DDrawModule ddrawModule;
- IDirectDrawSurface* p_surf_primary;
+ DDrawModule ddrawModule;
+ IDirectDrawSurface* p_surf_primary;
- tsk_thread_handle_t* tid[1];
+ tsk_thread_handle_t* tid[1];
- void* p_buff_rgb_aligned;
- tsk_size_t n_buff_rgb;
- tsk_size_t n_buff_rgb_bitscount;
+ void* p_buff_rgb_aligned;
+ tsk_size_t n_buff_rgb;
+ tsk_size_t n_buff_rgb_bitscount;
- void* p_buff_yuv_aligned;
- tsk_size_t n_buff_yuv;
+ void* p_buff_yuv_aligned;
+ tsk_size_t n_buff_yuv;
- BOOL b_have_rgb32_conv; // support for RGB32 -> I420 and primary screen format is RGB32
+ BOOL b_have_rgb32_conv; // support for RGB32 -> I420 and primary screen format is RGB32
- tsk_bool_t b_started;
- tsk_bool_t b_paused;
- tsk_bool_t b_muted;
+ tsk_bool_t b_started;
+ tsk_bool_t b_paused;
+ tsk_bool_t b_muted;
- TSK_DECLARE_SAFEOBJ;
+ TSK_DECLARE_SAFEOBJ;
}
tdav_producer_screencast_ddraw_t;
@@ -180,94 +179,94 @@ static HRESULT _tdav_producer_screencast_alloc_yuv_buff(tdav_producer_screencast
#if DDRAW_HAVE_RGB32_TO_I420_INTRIN || DDRAW_HAVE_RGB32_TO_I420_ASM
static __declspec(align(DDRAW_MEM_ALIGNMENT)) const int8_t kYCoeffs[16] = {
- 13, 65, 33, 0,
- 13, 65, 33, 0,
- 13, 65, 33, 0,
- 13, 65, 33, 0,
- };
- static __declspec(align(DDRAW_MEM_ALIGNMENT)) const int8_t kUCoeffs[16] = {
- 112, -74, -38, 0,
- 112, -74, -38, 0,
- 112, -74, -38, 0,
- 112, -74, -38, 0,
- };
- static __declspec(align(DDRAW_MEM_ALIGNMENT)) const int8_t kVCoeffs[16] = {
- -18, -94, 112, 0,
- -18, -94, 112, 0,
- -18, -94, 112, 0,
- -18, -94, 112, 0,
- };
- static __declspec(align(DDRAW_MEM_ALIGNMENT)) const int32_t kRGBAShuffleDuplicate[4] = { 0x03020100, 0x0b0a0908, 0x03020100, 0x0b0a0908 }; // RGBA(X) || RGBA(X + 2) || RGBA(X) || RGBA(X + 2) = 2U || 2V
- static __declspec(align(DDRAW_MEM_ALIGNMENT)) const uint16_t kY16[8] = {
- 16, 16, 16, 16,
- 16, 16, 16, 16
- };
- static __declspec(align(DDRAW_MEM_ALIGNMENT)) const uint16_t kUV128[8] = {
- 128, 128, 128, 128,
- 128, 128, 128, 128
- };
+ 13, 65, 33, 0,
+ 13, 65, 33, 0,
+ 13, 65, 33, 0,
+ 13, 65, 33, 0,
+};
+static __declspec(align(DDRAW_MEM_ALIGNMENT)) const int8_t kUCoeffs[16] = {
+ 112, -74, -38, 0,
+ 112, -74, -38, 0,
+ 112, -74, -38, 0,
+ 112, -74, -38, 0,
+};
+static __declspec(align(DDRAW_MEM_ALIGNMENT)) const int8_t kVCoeffs[16] = {
+ -18, -94, 112, 0,
+ -18, -94, 112, 0,
+ -18, -94, 112, 0,
+ -18, -94, 112, 0,
+};
+static __declspec(align(DDRAW_MEM_ALIGNMENT)) const int32_t kRGBAShuffleDuplicate[4] = { 0x03020100, 0x0b0a0908, 0x03020100, 0x0b0a0908 }; // RGBA(X) || RGBA(X + 2) || RGBA(X) || RGBA(X + 2) = 2U || 2V
+static __declspec(align(DDRAW_MEM_ALIGNMENT)) const uint16_t kY16[8] = {
+ 16, 16, 16, 16,
+ 16, 16, 16, 16
+};
+static __declspec(align(DDRAW_MEM_ALIGNMENT)) const uint16_t kUV128[8] = {
+ 128, 128, 128, 128,
+ 128, 128, 128, 128
+};
#endif /* DDRAW_HAVE_RGB32_TO_I420_INTRIN || DDRAW_HAVE_RGB32_TO_I420_ASM */
// public function used to check that we can use DDRAW plugin before loading it
tsk_bool_t tdav_producer_screencast_ddraw_plugin_is_supported()
{
- static tsk_bool_t __checked = tsk_false; // static guard to avoid checking more than once
- static tsk_bool_t __supported = tsk_false;
-
- HRESULT hr = DD_OK;
- DDSURFACEDESC ddsd;
- DDPIXELFORMAT DDPixelFormat;
- LPDIRECTDRAWSURFACE lpDDS = NULL;
- DDrawModule ddrawModule = { 0 };
-
- if (__checked) {
- goto bail;
- }
-
- __checked = tsk_true;
-
- DDRAW_CHECK_HR(hr = _tdav_producer_screencast_create_module(&ddrawModule));
- DDRAW_CHECK_HR(hr = ddrawModule.lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL));
-
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- DDRAW_CHECK_HR(hr = ddrawModule.lpDD->CreateSurface(&ddsd, &lpDDS, NULL));
-
- ZeroMemory(&DDPixelFormat, sizeof(DDPixelFormat));
- DDPixelFormat.dwSize = sizeof(DDPixelFormat);
- DDRAW_CHECK_HR(hr = lpDDS->GetPixelFormat(&DDPixelFormat));
- DDRAW_DEBUG_INFO("dwRGBBitCount:%d, dwRBitMask:%x, dwGBitMask:%x, dwBBitMask:%x, dwRGBAlphaBitMask:%x",
- DDPixelFormat.dwRGBBitCount, DDPixelFormat.dwRBitMask, DDPixelFormat.dwGBitMask, DDPixelFormat.dwBBitMask, DDPixelFormat.dwRGBAlphaBitMask);
- if (_tdav_producer_screencast_get_chroma(&DDPixelFormat) == tmedia_chroma_none) {
- DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
- }
+ static tsk_bool_t __checked = tsk_false; // static guard to avoid checking more than once
+ static tsk_bool_t __supported = tsk_false;
+
+ HRESULT hr = DD_OK;
+ DDSURFACEDESC ddsd;
+ DDPIXELFORMAT DDPixelFormat;
+ LPDIRECTDRAWSURFACE lpDDS = NULL;
+ DDrawModule ddrawModule = { 0 };
+
+ if (__checked) {
+ goto bail;
+ }
- __supported = SUCCEEDED(hr);
+ __checked = tsk_true;
+
+ DDRAW_CHECK_HR(hr = _tdav_producer_screencast_create_module(&ddrawModule));
+ DDRAW_CHECK_HR(hr = ddrawModule.lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL));
+
+ ZeroMemory(&ddsd, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = DDSD_CAPS;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+
+ DDRAW_CHECK_HR(hr = ddrawModule.lpDD->CreateSurface(&ddsd, &lpDDS, NULL));
+
+ ZeroMemory(&DDPixelFormat, sizeof(DDPixelFormat));
+ DDPixelFormat.dwSize = sizeof(DDPixelFormat);
+ DDRAW_CHECK_HR(hr = lpDDS->GetPixelFormat(&DDPixelFormat));
+ DDRAW_DEBUG_INFO("dwRGBBitCount:%d, dwRBitMask:%x, dwGBitMask:%x, dwBBitMask:%x, dwRGBAlphaBitMask:%x",
+ DDPixelFormat.dwRGBBitCount, DDPixelFormat.dwRBitMask, DDPixelFormat.dwGBitMask, DDPixelFormat.dwBBitMask, DDPixelFormat.dwRGBAlphaBitMask);
+ if (_tdav_producer_screencast_get_chroma(&DDPixelFormat) == tmedia_chroma_none) {
+ DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
+ }
+
+ __supported = SUCCEEDED(hr);
bail:
- DDRAW_SAFE_RELEASE(&lpDDS);
- DDrawModuleSafeFree(ddrawModule);
- return __supported;
+ DDRAW_SAFE_RELEASE(&lpDDS);
+ DDrawModuleSafeFree(ddrawModule);
+ return __supported;
}
static BOOL _tdav_producer_screencast_have_ssse3()
{
- static BOOL __checked = FALSE; // static guard to avoid checking more than once
- static BOOL __supported = FALSE;
+ static BOOL __checked = FALSE; // static guard to avoid checking more than once
+ static BOOL __supported = FALSE;
- if (__checked) {
- return __supported;
- }
- __checked = TRUE;
+ if (__checked) {
+ return __supported;
+ }
+ __checked = TRUE;
#ifndef BIT
# define BIT(n) (1<<n)
#endif /*BIT*/
#if DDRAW_HAVE_RGB32_TO_I420_ASM
- #define cpuid(func, func2, a, b, c, d)\
+#define cpuid(func, func2, a, b, c, d)\
__asm mov eax, func\
__asm mov ecx, func2\
__asm cpuid\
@@ -285,28 +284,28 @@ static BOOL _tdav_producer_screencast_have_ssse3()
#define HAS_AVX 0x40
#define HAS_AVX2 0x80
- unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx;
- cpuid(0, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
- if (reg_eax < 1) {
- DDRAW_DEBUG_ERROR("reg_eax < 1");
- return FALSE;
- }
- cpuid(1, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
- __supported = (reg_ecx & BIT(9)) ? TRUE : FALSE;
+ unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx;
+ cpuid(0, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
+ if (reg_eax < 1) {
+ DDRAW_DEBUG_ERROR("reg_eax < 1");
+ return FALSE;
+ }
+ cpuid(1, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
+ __supported = (reg_ecx & BIT(9)) ? TRUE : FALSE;
#elif DDRAW_HAVE_RGB32_TO_I420_INTRIN
- int cpu_info[4] = { 0 }, num_ids;
- __cpuid(cpu_info, 0);
- num_ids = cpu_info[0];
- __cpuid(cpu_info, 0x80000000);
- if (num_ids > 0) {
- __cpuid(cpu_info, 0x00000001);
- __supported = (cpu_info[2] & BIT(9)) ? TRUE : FALSE;
- }
+ int cpu_info[4] = { 0 }, num_ids;
+ __cpuid(cpu_info, 0);
+ num_ids = cpu_info[0];
+ __cpuid(cpu_info, 0x80000000);
+ if (num_ids > 0) {
+ __cpuid(cpu_info, 0x00000001);
+ __supported = (cpu_info[2] & BIT(9)) ? TRUE : FALSE;
+ }
#endif /* DDRAW_HAVE_RGB32_TO_I420_ASM */
- DDRAW_DEBUG_INFO("SSSE3 supported = %s", __supported ? "YES" : "NO");
+ DDRAW_DEBUG_INFO("SSSE3 supported = %s", __supported ? "YES" : "NO");
- return __supported;
+ return __supported;
}
#if DDRAW_HAVE_RGB32_TO_I420_INTRIN
@@ -327,105 +326,102 @@ static BOOL _tdav_producer_screencast_have_ssse3()
static void _tdav_producer_screencast_rgb32_to_yuv420_intrin_ssse3(uint8_t *yuvPtr, const uint8_t *rgbPtr, int width, int height)
{
- // rgbPtr contains (samplesCount * 16) bytes
- // yPtr contains samplesCount bytes
- const int samplesCount = (width * height); // "width" and "height" are in samples
- const uint8_t *rgbPtr_;
- uint8_t* yPtr_ = yuvPtr, *uPtr_ = (yPtr_ + samplesCount), *vPtr_ = uPtr_ + (samplesCount >> 2);
- __m128i mmRgb0, mmRgb1, mmRgb2, mmRgb3, mmY0, mmY1, mmY;
- __m128i mmRgbU0, mmRgbU1, mmRgbV0, mmRgbV1;
-
- // Convert 16 RGBA samples to 16 Y samples
- rgbPtr_ = rgbPtr;
- /* const */__m128i yCoeffs = _mm_load_si128((__m128i*)kYCoeffs);
- /* const */__m128i y16 = _mm_load_si128((__m128i*)kY16);
- for(int i = 0; i < samplesCount; i += 16)
- {
- // load 16 RGBA samples
- _mm_store_si128(&mmRgb0, _mm_load_si128((__m128i*)rgbPtr_)); // 4 RGBA samples
- _mm_store_si128(&mmRgb1, _mm_load_si128((__m128i*)&rgbPtr_[16])); // 4 RGBA samples
- _mm_store_si128(&mmRgb2, _mm_load_si128((__m128i*)&rgbPtr_[32])); // 4 RGBA samples
- _mm_store_si128(&mmRgb3, _mm_load_si128((__m128i*)&rgbPtr_[48])); // 4 RGBA samples
-
- _mm_store_si128(&mmRgb0, _mm_maddubs_epi16(mmRgb0/*unsigned*/, yCoeffs/*signed*/)); // mmRgb0 = ((yCoeffs[j] * mmRgb0[j]) + (yCoeffs[j + 1] * mmRgb0[j + 1]))
- _mm_store_si128(&mmRgb1, _mm_maddubs_epi16(mmRgb1/*unsigned*/, yCoeffs/*signed*/));
- _mm_store_si128(&mmRgb2, _mm_maddubs_epi16(mmRgb2/*unsigned*/, yCoeffs/*signed*/));
- _mm_store_si128(&mmRgb3, _mm_maddubs_epi16(mmRgb3/*unsigned*/, yCoeffs/*signed*/));
-
- _mm_store_si128(&mmY0, _mm_hadd_epi16(mmRgb0, mmRgb1)); // horizontal add
- _mm_store_si128(&mmY1, _mm_hadd_epi16(mmRgb2, mmRgb3));
-
- _mm_store_si128(&mmY0, _mm_srai_epi16(mmY0, 7)); // >> 7
- _mm_store_si128(&mmY1, _mm_srai_epi16(mmY1, 7));
-
- _mm_store_si128(&mmY0, _mm_add_epi16(mmY0, y16)); // + 16
- _mm_store_si128(&mmY1, _mm_add_epi16(mmY1, y16));
-
- _mm_store_si128(&mmY, _mm_packus_epi16(mmY0, mmY1)); // Saturate(I16 -> U8)
-
- _mm_store_si128((__m128i*)yPtr_, mmY);
-
- rgbPtr_ += 64; // 16samples * 4bytes
- yPtr_ += 16; // 16samples * 1byte
- }
+ // rgbPtr contains (samplesCount * 16) bytes
+ // yPtr contains samplesCount bytes
+ const int samplesCount = (width * height); // "width" and "height" are in samples
+ const uint8_t *rgbPtr_;
+ uint8_t* yPtr_ = yuvPtr, *uPtr_ = (yPtr_ + samplesCount), *vPtr_ = uPtr_ + (samplesCount >> 2);
+ __m128i mmRgb0, mmRgb1, mmRgb2, mmRgb3, mmY0, mmY1, mmY;
+ __m128i mmRgbU0, mmRgbU1, mmRgbV0, mmRgbV1;
+
+ // Convert 16 RGBA samples to 16 Y samples
+ rgbPtr_ = rgbPtr;
+ /* const */__m128i yCoeffs = _mm_load_si128((__m128i*)kYCoeffs);
+ /* const */__m128i y16 = _mm_load_si128((__m128i*)kY16);
+ for(int i = 0; i < samplesCount; i += 16) {
+ // load 16 RGBA samples
+ _mm_store_si128(&mmRgb0, _mm_load_si128((__m128i*)rgbPtr_)); // 4 RGBA samples
+ _mm_store_si128(&mmRgb1, _mm_load_si128((__m128i*)&rgbPtr_[16])); // 4 RGBA samples
+ _mm_store_si128(&mmRgb2, _mm_load_si128((__m128i*)&rgbPtr_[32])); // 4 RGBA samples
+ _mm_store_si128(&mmRgb3, _mm_load_si128((__m128i*)&rgbPtr_[48])); // 4 RGBA samples
+
+ _mm_store_si128(&mmRgb0, _mm_maddubs_epi16(mmRgb0/*unsigned*/, yCoeffs/*signed*/)); // mmRgb0 = ((yCoeffs[j] * mmRgb0[j]) + (yCoeffs[j + 1] * mmRgb0[j + 1]))
+ _mm_store_si128(&mmRgb1, _mm_maddubs_epi16(mmRgb1/*unsigned*/, yCoeffs/*signed*/));
+ _mm_store_si128(&mmRgb2, _mm_maddubs_epi16(mmRgb2/*unsigned*/, yCoeffs/*signed*/));
+ _mm_store_si128(&mmRgb3, _mm_maddubs_epi16(mmRgb3/*unsigned*/, yCoeffs/*signed*/));
+
+ _mm_store_si128(&mmY0, _mm_hadd_epi16(mmRgb0, mmRgb1)); // horizontal add
+ _mm_store_si128(&mmY1, _mm_hadd_epi16(mmRgb2, mmRgb3));
+
+ _mm_store_si128(&mmY0, _mm_srai_epi16(mmY0, 7)); // >> 7
+ _mm_store_si128(&mmY1, _mm_srai_epi16(mmY1, 7));
+
+ _mm_store_si128(&mmY0, _mm_add_epi16(mmY0, y16)); // + 16
+ _mm_store_si128(&mmY1, _mm_add_epi16(mmY1, y16));
+
+ _mm_store_si128(&mmY, _mm_packus_epi16(mmY0, mmY1)); // Saturate(I16 -> U8)
+
+ _mm_store_si128((__m128i*)yPtr_, mmY);
+
+ rgbPtr_ += 64; // 16samples * 4bytes
+ yPtr_ += 16; // 16samples * 1byte
+ }
- // U+V planes
- /* const */__m128i uCoeffs = _mm_load_si128((__m128i*)kUCoeffs);
- /* const */__m128i vCoeffs = _mm_load_si128((__m128i*)kVCoeffs);
- /* const */__m128i rgbaShuffleDuplicate = _mm_load_si128((__m128i*)kRGBAShuffleDuplicate);
- /* const */__m128i uv128 = _mm_load_si128((__m128i*)kUV128);
- rgbPtr_ = rgbPtr;
- for(int i = 0; i < samplesCount; )
- {
- // load 16 RGBA samples
- _mm_store_si128(&mmRgb0, _mm_load_si128((__m128i*)rgbPtr_)); // 4 RGBA samples
- _mm_store_si128(&mmRgb1, _mm_load_si128((__m128i*)&rgbPtr_[16])); // 4 RGBA samples
- _mm_store_si128(&mmRgb2, _mm_load_si128((__m128i*)&rgbPtr_[32])); // 4 RGBA samples
- _mm_store_si128(&mmRgb3, _mm_load_si128((__m128i*)&rgbPtr_[48])); // 4 RGBA samples
-
- _mm_store_si128(&mmRgb0, _mm_shuffle_epi8(mmRgb0, rgbaShuffleDuplicate));
- _mm_store_si128(&mmRgb1, _mm_shuffle_epi8(mmRgb1, rgbaShuffleDuplicate));
- _mm_store_si128(&mmRgb2, _mm_shuffle_epi8(mmRgb2, rgbaShuffleDuplicate));
- _mm_store_si128(&mmRgb3, _mm_shuffle_epi8(mmRgb3, rgbaShuffleDuplicate));
-
- _mm_store_si128(&mmRgbU0, _mm_unpacklo_epi64(mmRgb0, mmRgb1));
- _mm_store_si128(&mmRgbV0, _mm_unpackhi_epi64(mmRgb0, mmRgb1)); // same as mmRgbU0: Use _mm_store_si128??
- _mm_store_si128(&mmRgbU1, _mm_unpacklo_epi64(mmRgb2, mmRgb3));
- _mm_store_si128(&mmRgbV1, _mm_unpackhi_epi64(mmRgb2, mmRgb3)); // same as mmRgbU0: Use _mm_store_si128??
-
- _mm_store_si128(&mmRgbU0, _mm_maddubs_epi16(mmRgbU0/*unsigned*/, uCoeffs/*signed*/));
- _mm_store_si128(&mmRgbV0, _mm_maddubs_epi16(mmRgbV0/*unsigned*/, vCoeffs/*signed*/));
- _mm_store_si128(&mmRgbU1, _mm_maddubs_epi16(mmRgbU1/*unsigned*/, uCoeffs/*signed*/));
- _mm_store_si128(&mmRgbV1, _mm_maddubs_epi16(mmRgbV1/*unsigned*/, vCoeffs/*signed*/));
-
- _mm_store_si128(&mmY0, _mm_hadd_epi16(mmRgbU0, mmRgbU1)); // horizontal add
- _mm_store_si128(&mmY1, _mm_hadd_epi16(mmRgbV0, mmRgbV1));
-
- _mm_store_si128(&mmY0, _mm_srai_epi16(mmY0, 8)); // >> 8
- _mm_store_si128(&mmY1, _mm_srai_epi16(mmY1, 8));
-
- _mm_store_si128(&mmY0, _mm_add_epi16(mmY0, uv128)); // + 128
- _mm_store_si128(&mmY1, _mm_add_epi16(mmY1, uv128));
-
- // Y contains 8 samples for U then 8 samples for V
- _mm_store_si128(&mmY, _mm_packus_epi16(mmY0, mmY1)); // Saturate(I16 -> U8)
- _mm_storel_pi((__m64*)uPtr_, _mm_load_ps((float*)&mmY));
- _mm_storeh_pi((__m64*)vPtr_, _mm_load_ps((float*)&mmY));
-
- uPtr_ += 8; // 8samples * 1byte
- vPtr_ += 8; // 8samples * 1byte
-
- // move to next 16 samples
- i += 16;
- rgbPtr_ += 64; // 16samples * 4bytes
-
- if (/*i % width == 0*/ !(i & (width - 1)))
- {
- // skip next line
- i += width;
- rgbPtr_ += (width * 4);
- }
- }
+ // U+V planes
+ /* const */__m128i uCoeffs = _mm_load_si128((__m128i*)kUCoeffs);
+ /* const */__m128i vCoeffs = _mm_load_si128((__m128i*)kVCoeffs);
+ /* const */__m128i rgbaShuffleDuplicate = _mm_load_si128((__m128i*)kRGBAShuffleDuplicate);
+ /* const */__m128i uv128 = _mm_load_si128((__m128i*)kUV128);
+ rgbPtr_ = rgbPtr;
+ for(int i = 0; i < samplesCount; ) {
+ // load 16 RGBA samples
+ _mm_store_si128(&mmRgb0, _mm_load_si128((__m128i*)rgbPtr_)); // 4 RGBA samples
+ _mm_store_si128(&mmRgb1, _mm_load_si128((__m128i*)&rgbPtr_[16])); // 4 RGBA samples
+ _mm_store_si128(&mmRgb2, _mm_load_si128((__m128i*)&rgbPtr_[32])); // 4 RGBA samples
+ _mm_store_si128(&mmRgb3, _mm_load_si128((__m128i*)&rgbPtr_[48])); // 4 RGBA samples
+
+ _mm_store_si128(&mmRgb0, _mm_shuffle_epi8(mmRgb0, rgbaShuffleDuplicate));
+ _mm_store_si128(&mmRgb1, _mm_shuffle_epi8(mmRgb1, rgbaShuffleDuplicate));
+ _mm_store_si128(&mmRgb2, _mm_shuffle_epi8(mmRgb2, rgbaShuffleDuplicate));
+ _mm_store_si128(&mmRgb3, _mm_shuffle_epi8(mmRgb3, rgbaShuffleDuplicate));
+
+ _mm_store_si128(&mmRgbU0, _mm_unpacklo_epi64(mmRgb0, mmRgb1));
+ _mm_store_si128(&mmRgbV0, _mm_unpackhi_epi64(mmRgb0, mmRgb1)); // same as mmRgbU0: Use _mm_store_si128??
+ _mm_store_si128(&mmRgbU1, _mm_unpacklo_epi64(mmRgb2, mmRgb3));
+ _mm_store_si128(&mmRgbV1, _mm_unpackhi_epi64(mmRgb2, mmRgb3)); // same as mmRgbU0: Use _mm_store_si128??
+
+ _mm_store_si128(&mmRgbU0, _mm_maddubs_epi16(mmRgbU0/*unsigned*/, uCoeffs/*signed*/));
+ _mm_store_si128(&mmRgbV0, _mm_maddubs_epi16(mmRgbV0/*unsigned*/, vCoeffs/*signed*/));
+ _mm_store_si128(&mmRgbU1, _mm_maddubs_epi16(mmRgbU1/*unsigned*/, uCoeffs/*signed*/));
+ _mm_store_si128(&mmRgbV1, _mm_maddubs_epi16(mmRgbV1/*unsigned*/, vCoeffs/*signed*/));
+
+ _mm_store_si128(&mmY0, _mm_hadd_epi16(mmRgbU0, mmRgbU1)); // horizontal add
+ _mm_store_si128(&mmY1, _mm_hadd_epi16(mmRgbV0, mmRgbV1));
+
+ _mm_store_si128(&mmY0, _mm_srai_epi16(mmY0, 8)); // >> 8
+ _mm_store_si128(&mmY1, _mm_srai_epi16(mmY1, 8));
+
+ _mm_store_si128(&mmY0, _mm_add_epi16(mmY0, uv128)); // + 128
+ _mm_store_si128(&mmY1, _mm_add_epi16(mmY1, uv128));
+
+ // Y contains 8 samples for U then 8 samples for V
+ _mm_store_si128(&mmY, _mm_packus_epi16(mmY0, mmY1)); // Saturate(I16 -> U8)
+ _mm_storel_pi((__m64*)uPtr_, _mm_load_ps((float*)&mmY));
+ _mm_storeh_pi((__m64*)vPtr_, _mm_load_ps((float*)&mmY));
+
+ uPtr_ += 8; // 8samples * 1byte
+ vPtr_ += 8; // 8samples * 1byte
+
+ // move to next 16 samples
+ i += 16;
+ rgbPtr_ += 64; // 16samples * 4bytes
+
+ if (/*i % width == 0*/ !(i & (width - 1))) {
+ // skip next line
+ i += width;
+ rgbPtr_ += (width * 4);
+ }
+ }
}
#endif /* DDRAW_HAVE_RGB32_TO_I420_INTRIN */
@@ -502,917 +498,917 @@ static void _tdav_producer_screencast_rgb32_to_yuv420_intrin_ssse3(uint8_t *yuvP
__declspec(naked) __declspec(align(DDRAW_MEM_ALIGNMENT))
static void _tdav_producer_screencast_rgb32_to_yuv420_asm_ssse3(uint8_t *yuvPtr, const uint8_t *rgbPtr, int width, int height)
{
- __asm {
- push esi
- push edi
- push ebx
- /*** Y Samples ***/
- mov edx, [esp + 12 + 4] // yuvPtr
- mov eax, [esp + 12 + 8] // rgbPtr
- mov ecx, [esp + 12 + 12] // width
- imul ecx, [esp + 12 + 16] // (width * height) = samplesCount
-
- movdqa xmm7, kYCoeffs // yCoeffs
- movdqa xmm6, kY16 // y16
- /* loopY start */
-loopY:
- // load 16 RGBA samples
- movdqa xmm0, [eax] // mmRgb0
- movdqa xmm1, [eax + 16] // mmRgb1
- movdqa xmm2, [eax + 32] // mmRgb2
- movdqa xmm3, [eax + 48] // mmRgb3
- lea eax, [eax + 64] // rgbPtr_ += 64
- // (yCoeffs[0] * mmRgbX[0]) + (yCoeffs[1] * mmRgbX[1])
- pmaddubsw xmm0, xmm7
- pmaddubsw xmm1, xmm7
- pmaddubsw xmm2, xmm7
- pmaddubsw xmm3, xmm7
- // horizontal add
- phaddw xmm0, xmm1
- phaddw xmm2, xmm3
- // >> 7
- psraw xmm0, 7
- psraw xmm2, 7
- // + 16
- paddw xmm0, xmm6
- paddw xmm2, xmm6
- // Saturate(I16 -> U8) - Packs
- packuswb xmm0, xmm2
- // Copy to yuvPtr
- movdqa [edx], xmm0
- lea edx, [edx + 16] // yPtr_ += 16
- sub ecx, 16 // samplesCount -= 16
- jnz loopY // goto loop if (samplesCount != 0)
-
- //==================================//
- //=========== UV Samples ===========//
- //==================================//
- mov esi, [esp + 12 + 4] // yuvPtr
- mov eax, [esp + 12 + 8] // rgbPtr
- mov ecx, [esp + 12 + 12] // width
- imul ecx, [esp + 12 + 16] // (width * height) = samplesCount
- mov edx, ecx
- shr edx, 2 // edx = samplesCount / 4
- add esi, ecx // [[esi = uPtr_]]
- mov edi, esi // edi = uPtr_
- add edi, edx // [[edi = uPtr_ + edx = uPtr_ + (samplesCount / 4) = vPtr_]]
- xor edx, edx // edx = 0 = i
- mov ebx, [esp + 12 + 12] // ebx = width
- sub ebx, 1 // ebx = (width - 1)
-
- movdqa xmm7, kUCoeffs // uCoeffs
- movdqa xmm6, kVCoeffs // vCoeffs
- movdqa xmm5, kRGBAShuffleDuplicate // rgbaShuffleDuplicate
- movdqa xmm4, kUV128 // uv128
-
- /* loopUV start */
-loopUV:
- // load 16 RGBA samples
- movdqa xmm0, [eax] // mmRgb0
- movdqa xmm1, [eax + 16] // mmRgb1
- movdqa xmm2, [eax + 32] // mmRgb2
- movdqa xmm3, [eax + 48] // mmRgb3
- lea eax, [eax + 64] // rgbPtr_ += 64
-
- pshufb xmm0, xmm5
- pshufb xmm1, xmm5
- pshufb xmm2, xmm5
- pshufb xmm3, xmm5
-
- punpcklqdq xmm0, xmm1 // mmRgbU0
- punpcklqdq xmm2, xmm3 // mmRgbU1
- movdqa xmm1, xmm0 // mmRgbV0
- movdqa xmm3, xmm2 // mmRgbV1
-
- pmaddubsw xmm0, xmm7 // mmRgbU0
- pmaddubsw xmm1, xmm6 // mmRgbV0
- pmaddubsw xmm2, xmm7 // mmRgbU1
- pmaddubsw xmm3, xmm6 // mmRgbV1
-
- phaddw xmm0, xmm2 // mmY0
- phaddw xmm1, xmm3 // mmY1
-
- psraw xmm0, 8
- psraw xmm1, 8
-
- paddw xmm0, xmm4
- paddw xmm1, xmm4
-
- packuswb xmm0, xmm1
- movlps [esi], xmm0
- movhps [edi], xmm0
-
- lea esi, [esi + 8]
- lea edi, [edi + 8]
-
- add edx, 16 // i += 16;
- push edx // save edx
- and edx, ebx // edx = (ebx & ebx) = (ebx & (width - 1)) = (ebx % width)
- cmp edx, 0 // (ebx % width) == 0 ?
- pop edx // restore edx
- jne loopUV_NextLine
-
- // loopUV_EndOfLine: ((ebx % width) == 0)
- add ebx, 1// change ebx value from width-1 to width
- add edx, ebx // i += width
- lea eax, [eax + 4 * ebx]// rgbPtr_ += (width * 4);
- sub ebx, 1// change back ebx value to width - 1
-loopUV_NextLine:
- cmp edx, ecx
- jl loopUV
-
- pop ebx
- pop edi
- pop esi
- ret
- }
+ __asm {
+ push esi
+ push edi
+ push ebx
+ /*** Y Samples ***/
+ mov edx, [esp + 12 + 4] // yuvPtr
+ mov eax, [esp + 12 + 8] // rgbPtr
+ mov ecx, [esp + 12 + 12] // width
+ imul ecx, [esp + 12 + 16] // (width * height) = samplesCount
+
+ movdqa xmm7, kYCoeffs // yCoeffs
+ movdqa xmm6, kY16 // y16
+ /* loopY start */
+ loopY:
+ // load 16 RGBA samples
+ movdqa xmm0, [eax] // mmRgb0
+ movdqa xmm1, [eax + 16] // mmRgb1
+ movdqa xmm2, [eax + 32] // mmRgb2
+ movdqa xmm3, [eax + 48] // mmRgb3
+ lea eax, [eax + 64] // rgbPtr_ += 64
+ // (yCoeffs[0] * mmRgbX[0]) + (yCoeffs[1] * mmRgbX[1])
+ pmaddubsw xmm0, xmm7
+ pmaddubsw xmm1, xmm7
+ pmaddubsw xmm2, xmm7
+ pmaddubsw xmm3, xmm7
+ // horizontal add
+ phaddw xmm0, xmm1
+ phaddw xmm2, xmm3
+ // >> 7
+ psraw xmm0, 7
+ psraw xmm2, 7
+ // + 16
+ paddw xmm0, xmm6
+ paddw xmm2, xmm6
+ // Saturate(I16 -> U8) - Packs
+ packuswb xmm0, xmm2
+ // Copy to yuvPtr
+ movdqa [edx], xmm0
+ lea edx, [edx + 16] // yPtr_ += 16
+ sub ecx, 16 // samplesCount -= 16
+ jnz loopY // goto loop if (samplesCount != 0)
+
+ //==================================//
+ //=========== UV Samples ===========//
+ //==================================//
+ mov esi, [esp + 12 + 4] // yuvPtr
+ mov eax, [esp + 12 + 8] // rgbPtr
+ mov ecx, [esp + 12 + 12] // width
+ imul ecx, [esp + 12 + 16] // (width * height) = samplesCount
+ mov edx, ecx
+ shr edx, 2 // edx = samplesCount / 4
+ add esi, ecx // [[esi = uPtr_]]
+ mov edi, esi // edi = uPtr_
+ add edi, edx // [[edi = uPtr_ + edx = uPtr_ + (samplesCount / 4) = vPtr_]]
+ xor edx, edx // edx = 0 = i
+ mov ebx, [esp + 12 + 12] // ebx = width
+ sub ebx, 1 // ebx = (width - 1)
+
+ movdqa xmm7, kUCoeffs // uCoeffs
+ movdqa xmm6, kVCoeffs // vCoeffs
+ movdqa xmm5, kRGBAShuffleDuplicate // rgbaShuffleDuplicate
+ movdqa xmm4, kUV128 // uv128
+
+ /* loopUV start */
+ loopUV:
+ // load 16 RGBA samples
+ movdqa xmm0, [eax] // mmRgb0
+ movdqa xmm1, [eax + 16] // mmRgb1
+ movdqa xmm2, [eax + 32] // mmRgb2
+ movdqa xmm3, [eax + 48] // mmRgb3
+ lea eax, [eax + 64] // rgbPtr_ += 64
+
+ pshufb xmm0, xmm5
+ pshufb xmm1, xmm5
+ pshufb xmm2, xmm5
+ pshufb xmm3, xmm5
+
+ punpcklqdq xmm0, xmm1 // mmRgbU0
+ punpcklqdq xmm2, xmm3 // mmRgbU1
+ movdqa xmm1, xmm0 // mmRgbV0
+ movdqa xmm3, xmm2 // mmRgbV1
+
+ pmaddubsw xmm0, xmm7 // mmRgbU0
+ pmaddubsw xmm1, xmm6 // mmRgbV0
+ pmaddubsw xmm2, xmm7 // mmRgbU1
+ pmaddubsw xmm3, xmm6 // mmRgbV1
+
+ phaddw xmm0, xmm2 // mmY0
+ phaddw xmm1, xmm3 // mmY1
+
+ psraw xmm0, 8
+ psraw xmm1, 8
+
+ paddw xmm0, xmm4
+ paddw xmm1, xmm4
+
+ packuswb xmm0, xmm1
+ movlps [esi], xmm0
+ movhps [edi], xmm0
+
+ lea esi, [esi + 8]
+ lea edi, [edi + 8]
+
+ add edx, 16 // i += 16;
+ push edx // save edx
+ and edx, ebx // edx = (ebx & ebx) = (ebx & (width - 1)) = (ebx % width)
+ cmp edx, 0 // (ebx % width) == 0 ?
+ pop edx // restore edx
+ jne loopUV_NextLine
+
+ // loopUV_EndOfLine: ((ebx % width) == 0)
+ add ebx, 1// change ebx value from width-1 to width
+ add edx, ebx // i += width
+ lea eax, [eax + 4 * ebx]// rgbPtr_ += (width * 4);
+ sub ebx, 1// change back ebx value to width - 1
+ loopUV_NextLine:
+ cmp edx, ecx
+ jl loopUV
+
+ pop ebx
+ pop edi
+ pop esi
+ ret
+ }
}
#endif /* DDRAW_HAVE_RGB32_TO_I420_ASM */
/* ============ Media Producer Interface ================= */
static int _tdav_producer_screencast_ddraw_set(tmedia_producer_t *p_self, const tmedia_param_t* pc_param)
{
- int ret = 0;
- tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
+ int ret = 0;
+ tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
- if (!p_ddraw || !pc_param) {
- DDRAW_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_ddraw || !pc_param) {
+ DDRAW_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- if (pc_param->value_type == tmedia_pvt_int64) {
- if (tsk_striequals(pc_param->key, "local-hwnd") || tsk_striequals(pc_param->key, "preview-hwnd")) {
- p_ddraw->hwnd_preview = (HWND)*((int64_t*)pc_param->value);
- }
- else if (tsk_striequals(pc_param->key, "src-hwnd")) {
- p_ddraw->hwnd_src = (HWND)*((int64_t*)pc_param->value);
- }
- }
- else if (pc_param->value_type == tmedia_pvt_int32) {
- if (tsk_striequals(pc_param->key, "mute")) {
- p_ddraw->b_muted = (TSK_TO_INT32((uint8_t*)pc_param->value) != 0);
- }
- }
+ if (pc_param->value_type == tmedia_pvt_int64) {
+ if (tsk_striequals(pc_param->key, "local-hwnd") || tsk_striequals(pc_param->key, "preview-hwnd")) {
+ p_ddraw->hwnd_preview = (HWND)*((int64_t*)pc_param->value);
+ }
+ else if (tsk_striequals(pc_param->key, "src-hwnd")) {
+ p_ddraw->hwnd_src = (HWND)*((int64_t*)pc_param->value);
+ }
+ }
+ else if (pc_param->value_type == tmedia_pvt_int32) {
+ if (tsk_striequals(pc_param->key, "mute")) {
+ p_ddraw->b_muted = (TSK_TO_INT32((uint8_t*)pc_param->value) != 0);
+ }
+ }
- return ret;
+ return ret;
}
static int _tdav_producer_screencast_ddraw_prepare(tmedia_producer_t* p_self, const tmedia_codec_t* pc_codec)
{
- tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
- int ret = 0;
- HRESULT hr = DD_OK;
+ tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
+ int ret = 0;
+ HRESULT hr = DD_OK;
#if 0
- DDPIXELFORMAT DDPixelFormat;
+ DDPIXELFORMAT DDPixelFormat;
#endif
- DDSURFACEDESC ddsd;
+ DDSURFACEDESC ddsd;
- if (!p_ddraw || !pc_codec) {
- DDRAW_DEBUG_ERROR("Invalid parameter");
- DDRAW_CHECK_HR(hr = E_INVALIDARG);
- }
+ if (!p_ddraw || !pc_codec) {
+ DDRAW_DEBUG_ERROR("Invalid parameter");
+ DDRAW_CHECK_HR(hr = E_INVALIDARG);
+ }
- tsk_safeobj_lock(p_ddraw);
+ tsk_safeobj_lock(p_ddraw);
- // check support for DirectDraw again
- if (!tdav_producer_screencast_ddraw_plugin_is_supported()) {
- DDRAW_CHECK_HR(hr = E_FAIL);
- }
+ // check support for DirectDraw again
+ if (!tdav_producer_screencast_ddraw_plugin_is_supported()) {
+ DDRAW_CHECK_HR(hr = E_FAIL);
+ }
- TMEDIA_PRODUCER(p_ddraw)->video.fps = TMEDIA_CODEC_VIDEO(pc_codec)->out.fps;
- TMEDIA_PRODUCER(p_ddraw)->video.width = TMEDIA_CODEC_VIDEO(pc_codec)->out.width;
- TMEDIA_PRODUCER(p_ddraw)->video.height = TMEDIA_CODEC_VIDEO(pc_codec)->out.height;
-
- // Hack the codec to avoid flipping
- TMEDIA_CODEC_VIDEO(pc_codec)->out.flip = tsk_false;
+ TMEDIA_PRODUCER(p_ddraw)->video.fps = TMEDIA_CODEC_VIDEO(pc_codec)->out.fps;
+ TMEDIA_PRODUCER(p_ddraw)->video.width = TMEDIA_CODEC_VIDEO(pc_codec)->out.width;
+ TMEDIA_PRODUCER(p_ddraw)->video.height = TMEDIA_CODEC_VIDEO(pc_codec)->out.height;
- DDRAW_DEBUG_INFO("Prepare with fps:%d, width:%d; height:%d", TMEDIA_PRODUCER(p_ddraw)->video.fps, TMEDIA_PRODUCER(p_ddraw)->video.width, TMEDIA_PRODUCER(p_ddraw)->video.height);
+ // Hack the codec to avoid flipping
+ TMEDIA_CODEC_VIDEO(pc_codec)->out.flip = tsk_false;
- if (!p_ddraw->ddrawModule.lpDD || !p_ddraw->ddrawModule.hDLL) {
- DDRAW_CHECK_HR(hr = _tdav_producer_screencast_create_module(&p_ddraw->ddrawModule));
- }
- DDRAW_CHECK_HR(hr = p_ddraw->ddrawModule.lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL));
-
- if (!p_ddraw->p_surf_primary) {
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- DDRAW_CHECK_HR(hr = p_ddraw->ddrawModule.lpDD->CreateSurface(&ddsd, &p_ddraw->p_surf_primary, NULL));
- }
+ DDRAW_DEBUG_INFO("Prepare with fps:%d, width:%d; height:%d", TMEDIA_PRODUCER(p_ddraw)->video.fps, TMEDIA_PRODUCER(p_ddraw)->video.width, TMEDIA_PRODUCER(p_ddraw)->video.height);
+
+ if (!p_ddraw->ddrawModule.lpDD || !p_ddraw->ddrawModule.hDLL) {
+ DDRAW_CHECK_HR(hr = _tdav_producer_screencast_create_module(&p_ddraw->ddrawModule));
+ }
+ DDRAW_CHECK_HR(hr = p_ddraw->ddrawModule.lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL));
+
+ if (!p_ddraw->p_surf_primary) {
+ ZeroMemory(&ddsd, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = DDSD_CAPS;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+
+ DDRAW_CHECK_HR(hr = p_ddraw->ddrawModule.lpDD->CreateSurface(&ddsd, &p_ddraw->p_surf_primary, NULL));
+ }
#if 0
- ZeroMemory(&DDPixelFormat, sizeof(DDPixelFormat));
- DDPixelFormat.dwSize = sizeof(DDPixelFormat);
- DDRAW_CHECK_HR(hr = DDRAW_VTBL(p_ddraw->p_surf_primary)->GetPixelFormat(p_ddraw->p_surf_primary, &DDPixelFormat));
- DDRAW_DEBUG_INFO("dwRGBBitCount:%d, dwRBitMask:%x, dwGBitMask:%x, dwBBitMask:%x, dwRGBAlphaBitMask:%x",
- DDPixelFormat.dwRGBBitCount, DDPixelFormat.dwRBitMask, DDPixelFormat.dwGBitMask, DDPixelFormat.dwBBitMask, DDPixelFormat.dwRGBAlphaBitMask);
- if ((TMEDIA_PRODUCER(p_ddraw)->video.chroma = _tdav_producer_screencast_get_chroma(&DDPixelFormat)) == tmedia_chroma_none) {
- DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
- }
+ ZeroMemory(&DDPixelFormat, sizeof(DDPixelFormat));
+ DDPixelFormat.dwSize = sizeof(DDPixelFormat);
+ DDRAW_CHECK_HR(hr = DDRAW_VTBL(p_ddraw->p_surf_primary)->GetPixelFormat(p_ddraw->p_surf_primary, &DDPixelFormat));
+ DDRAW_DEBUG_INFO("dwRGBBitCount:%d, dwRBitMask:%x, dwGBitMask:%x, dwBBitMask:%x, dwRGBAlphaBitMask:%x",
+ DDPixelFormat.dwRGBBitCount, DDPixelFormat.dwRBitMask, DDPixelFormat.dwGBitMask, DDPixelFormat.dwBBitMask, DDPixelFormat.dwRGBAlphaBitMask);
+ if ((TMEDIA_PRODUCER(p_ddraw)->video.chroma = _tdav_producer_screencast_get_chroma(&DDPixelFormat)) == tmedia_chroma_none) {
+ DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
+ }
#else
- ZeroMemory(&ddsd, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT;
- DDRAW_CHECK_HR(hr = p_ddraw->p_surf_primary->GetSurfaceDesc(&ddsd));
- DDRAW_DEBUG_INFO("Prepare with neg. width:%d, height:%d, pitch=%ld", ddsd.dwWidth, ddsd.dwHeight, ddsd.lPitch);
- TMEDIA_PRODUCER(p_ddraw)->video.width = ddsd.dwWidth;
- TMEDIA_PRODUCER(p_ddraw)->video.height = ddsd.dwHeight;
- p_ddraw->n_buff_rgb_bitscount = ddsd.ddpfPixelFormat.dwRGBBitCount;
- DDRAW_DEBUG_INFO("Prepare with dwRGBBitCount:%d, dwRBitMask:%x, dwGBitMask:%x, dwBBitMask:%x, dwRGBAlphaBitMask:%x",
- ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.ddpfPixelFormat.dwRBitMask, ddsd.ddpfPixelFormat.dwGBitMask, ddsd.ddpfPixelFormat.dwBBitMask, ddsd.ddpfPixelFormat.dwRGBAlphaBitMask);
- if ((TMEDIA_PRODUCER(p_ddraw)->video.chroma = _tdav_producer_screencast_get_chroma(&ddsd.ddpfPixelFormat)) == tmedia_chroma_none) {
- DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
- }
+ ZeroMemory(&ddsd, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT;
+ DDRAW_CHECK_HR(hr = p_ddraw->p_surf_primary->GetSurfaceDesc(&ddsd));
+ DDRAW_DEBUG_INFO("Prepare with neg. width:%d, height:%d, pitch=%ld", ddsd.dwWidth, ddsd.dwHeight, ddsd.lPitch);
+ TMEDIA_PRODUCER(p_ddraw)->video.width = ddsd.dwWidth;
+ TMEDIA_PRODUCER(p_ddraw)->video.height = ddsd.dwHeight;
+ p_ddraw->n_buff_rgb_bitscount = ddsd.ddpfPixelFormat.dwRGBBitCount;
+ DDRAW_DEBUG_INFO("Prepare with dwRGBBitCount:%d, dwRBitMask:%x, dwGBitMask:%x, dwBBitMask:%x, dwRGBAlphaBitMask:%x",
+ ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.ddpfPixelFormat.dwRBitMask, ddsd.ddpfPixelFormat.dwGBitMask, ddsd.ddpfPixelFormat.dwBBitMask, ddsd.ddpfPixelFormat.dwRGBAlphaBitMask);
+ if ((TMEDIA_PRODUCER(p_ddraw)->video.chroma = _tdav_producer_screencast_get_chroma(&ddsd.ddpfPixelFormat)) == tmedia_chroma_none) {
+ DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
+ }
#endif
- // allocate RGB buffer
- DDRAW_CHECK_HR(hr = _tdav_producer_screencast_alloc_rgb_buff(p_ddraw, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount));
+ // allocate RGB buffer
+ DDRAW_CHECK_HR(hr = _tdav_producer_screencast_alloc_rgb_buff(p_ddraw, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount));
- // Check if we can use built-in chroma conversion
+ // Check if we can use built-in chroma conversion
#if DDRAW_HAVE_RGB32_TO_I420_INTRIN || DDRAW_HAVE_RGB32_TO_I420_ASM
- p_ddraw->b_have_rgb32_conv =
- _tdav_producer_screencast_have_ssse3() // SSSE3 supported
- && DDRAW_IS_ALIGNED(TMEDIA_PRODUCER(p_ddraw)->video.width, DDRAW_MEM_ALIGNMENT) // width multiple of 16
- /* && DDRAW_IS_ALIGNED(TMEDIA_PRODUCER(p_ddraw)->video.height, DDRAW_MEM_ALIGNMENT) // height multiple of 16 */
- && TMEDIA_PRODUCER(p_ddraw)->video.chroma == tmedia_chroma_rgb32; // Primary screen RGB32
- if (p_ddraw->b_have_rgb32_conv) {
- TMEDIA_PRODUCER(p_ddraw)->video.chroma = tmedia_chroma_yuv420p;
- }
+ p_ddraw->b_have_rgb32_conv =
+ _tdav_producer_screencast_have_ssse3() // SSSE3 supported
+ && DDRAW_IS_ALIGNED(TMEDIA_PRODUCER(p_ddraw)->video.width, DDRAW_MEM_ALIGNMENT) // width multiple of 16
+ /* && DDRAW_IS_ALIGNED(TMEDIA_PRODUCER(p_ddraw)->video.height, DDRAW_MEM_ALIGNMENT) // height multiple of 16 */
+ && TMEDIA_PRODUCER(p_ddraw)->video.chroma == tmedia_chroma_rgb32; // Primary screen RGB32
+ if (p_ddraw->b_have_rgb32_conv) {
+ TMEDIA_PRODUCER(p_ddraw)->video.chroma = tmedia_chroma_yuv420p;
+ }
#endif
- DDRAW_DEBUG_INFO("RGB32 -> I420 conversion supported: %s", p_ddraw->b_have_rgb32_conv ? "YES" : "NO");
+ DDRAW_DEBUG_INFO("RGB32 -> I420 conversion supported: %s", p_ddraw->b_have_rgb32_conv ? "YES" : "NO");
- // allocate YUV buffer
- if (p_ddraw->b_have_rgb32_conv) {
- DDRAW_CHECK_HR(hr = _tdav_producer_screencast_alloc_yuv_buff(p_ddraw, (DWORD)TMEDIA_PRODUCER(p_ddraw)->video.width, (DWORD)TMEDIA_PRODUCER(p_ddraw)->video.height));
- }
+ // allocate YUV buffer
+ if (p_ddraw->b_have_rgb32_conv) {
+ DDRAW_CHECK_HR(hr = _tdav_producer_screencast_alloc_yuv_buff(p_ddraw, (DWORD)TMEDIA_PRODUCER(p_ddraw)->video.width, (DWORD)TMEDIA_PRODUCER(p_ddraw)->video.height));
+ }
- // BitmapInfo for preview
+ // BitmapInfo for preview
#if DDRAW_PREVIEW
- ZeroMemory(&p_ddraw->bi_preview, sizeof(p_ddraw->bi_preview));
- p_ddraw->bi_preview.bmiHeader.biSize = (DWORD)sizeof(BITMAPINFOHEADER);
- p_ddraw->bi_preview.bmiHeader.biCompression = BI_RGB;
- p_ddraw->bi_preview.bmiHeader.biPlanes = 1;
- p_ddraw->bi_preview.bmiHeader.biWidth = ddsd.dwWidth;
- p_ddraw->bi_preview.bmiHeader.biHeight = ddsd.dwHeight;
- p_ddraw->bi_preview.bmiHeader.biBitCount = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount;
- p_ddraw->bi_preview.bmiHeader.biSizeImage = (p_ddraw->bi_preview.bmiHeader.biWidth * p_ddraw->bi_preview.bmiHeader.biHeight * (p_ddraw->bi_preview.bmiHeader.biBitCount >> 3));
+ ZeroMemory(&p_ddraw->bi_preview, sizeof(p_ddraw->bi_preview));
+ p_ddraw->bi_preview.bmiHeader.biSize = (DWORD)sizeof(BITMAPINFOHEADER);
+ p_ddraw->bi_preview.bmiHeader.biCompression = BI_RGB;
+ p_ddraw->bi_preview.bmiHeader.biPlanes = 1;
+ p_ddraw->bi_preview.bmiHeader.biWidth = ddsd.dwWidth;
+ p_ddraw->bi_preview.bmiHeader.biHeight = ddsd.dwHeight;
+ p_ddraw->bi_preview.bmiHeader.biBitCount = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount;
+ p_ddraw->bi_preview.bmiHeader.biSizeImage = (p_ddraw->bi_preview.bmiHeader.biWidth * p_ddraw->bi_preview.bmiHeader.biHeight * (p_ddraw->bi_preview.bmiHeader.biBitCount >> 3));
#endif /* DDRAW_PREVIEW */
#if DDRAW_CPU_MONITOR || DDRAW_CPU_THROTTLING
- if (!p_ddraw->p_timer_mgr) {
- p_ddraw->p_timer_mgr = tsk_timer_manager_create();
- }
+ if (!p_ddraw->p_timer_mgr) {
+ p_ddraw->p_timer_mgr = tsk_timer_manager_create();
+ }
#endif /* DDRAW_CPU_MONITOR ||DDRAW_CPU_THROTTLING */
#if DDRAW_CPU_THROTTLING
- p_ddraw->cpu.fps_target = (TMEDIA_PRODUCER(p_ddraw)->video.fps + DDRAW_CPU_THROTTLING_FPS_MIN) >> 1; // start with minimum fps and increase the value based on the fps
+ p_ddraw->cpu.fps_target = (TMEDIA_PRODUCER(p_ddraw)->video.fps + DDRAW_CPU_THROTTLING_FPS_MIN) >> 1; // start with minimum fps and increase the value based on the fps
#endif /* DDRAW_CPU_THROTTLING */
-bail:
- tsk_safeobj_unlock(p_ddraw);
- return SUCCEEDED(hr) ? 0 : -1;
+ bail:
+ tsk_safeobj_unlock(p_ddraw);
+ return SUCCEEDED(hr) ? 0 : -1;
}
static int _tdav_producer_screencast_ddraw_start(tmedia_producer_t* p_self)
{
- tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
- int ret = 0;
+ tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
+ int ret = 0;
- if (!p_ddraw) {
- DDRAW_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_ddraw) {
+ DDRAW_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- ret = tsk_safeobj_lock(p_ddraw);
+ ret = tsk_safeobj_lock(p_ddraw);
- p_ddraw->b_paused = tsk_false;
+ p_ddraw->b_paused = tsk_false;
- if (p_ddraw->b_started) {
- DDRAW_DEBUG_INFO("Already started");
- goto bail;
- }
+ if (p_ddraw->b_started) {
+ DDRAW_DEBUG_INFO("Already started");
+ goto bail;
+ }
- p_ddraw->b_started = tsk_true;
+ p_ddraw->b_started = tsk_true;
- // Create notify events (must be done here before starting the grabber thread)
+ // Create notify events (must be done here before starting the grabber thread)
#if DDRAW_MT
- for (int i = 0; i < sizeof(p_ddraw->mt.h_events) / sizeof(p_ddraw->mt.h_events[0]); ++i) {
- if (!p_ddraw->mt.h_events[i] && !(p_ddraw->mt.h_events[i] = CreateEvent(NULL, FALSE, FALSE, NULL))) {
- DDRAW_DEBUG_ERROR("Failed to create event at %d", i);
- ret = -1;
- goto bail;
- }
- }
+ for (int i = 0; i < sizeof(p_ddraw->mt.h_events) / sizeof(p_ddraw->mt.h_events[0]); ++i) {
+ if (!p_ddraw->mt.h_events[i] && !(p_ddraw->mt.h_events[i] = CreateEvent(NULL, FALSE, FALSE, NULL))) {
+ DDRAW_DEBUG_ERROR("Failed to create event at %d", i);
+ ret = -1;
+ goto bail;
+ }
+ }
#endif /* DDRAW_MT */
- ret = tsk_thread_create(&p_ddraw->tid[0], _tdav_producer_screencast_grap_thread, p_ddraw);
- if (ret != 0) {
- DDRAW_DEBUG_ERROR("Failed to create thread");
- goto bail;
- }
- //BOOL okSetTA = CeSetThreadAffinity((HANDLE)p_ddraw->tid[0], 0x01);
+ ret = tsk_thread_create(&p_ddraw->tid[0], _tdav_producer_screencast_grap_thread, p_ddraw);
+ if (ret != 0) {
+ DDRAW_DEBUG_ERROR("Failed to create thread");
+ goto bail;
+ }
+ //BOOL okSetTA = CeSetThreadAffinity((HANDLE)p_ddraw->tid[0], 0x01);
#if DDRAW_MT
- ret = tsk_thread_create(&p_ddraw->mt.tid[0], _tdav_producer_screencast_mt_encode_thread, p_ddraw);
- if (ret != 0) {
- DDRAW_DEBUG_ERROR("Failed to create thread");
- goto bail;
- }
- //okSetTA = CeSetThreadAffinity((HANDLE)p_ddraw->mt.tid[0], 0x02);
+ ret = tsk_thread_create(&p_ddraw->mt.tid[0], _tdav_producer_screencast_mt_encode_thread, p_ddraw);
+ if (ret != 0) {
+ DDRAW_DEBUG_ERROR("Failed to create thread");
+ goto bail;
+ }
+ //okSetTA = CeSetThreadAffinity((HANDLE)p_ddraw->mt.tid[0], 0x02);
#endif /* DDRAW_MT */
#if DDRAW_HIGH_PRIO_MEMCPY
- if (p_ddraw->tid[0]) {
- tsk_thread_set_priority(p_ddraw->tid[0], TSK_THREAD_PRIORITY_TIME_CRITICAL);
- }
+ if (p_ddraw->tid[0]) {
+ tsk_thread_set_priority(p_ddraw->tid[0], TSK_THREAD_PRIORITY_TIME_CRITICAL);
+ }
#if DDRAW_MT
- if (p_ddraw->mt.tid[0]) {
- tsk_thread_set_priority(p_ddraw->mt.tid[0], TSK_THREAD_PRIORITY_TIME_CRITICAL);
- }
+ if (p_ddraw->mt.tid[0]) {
+ tsk_thread_set_priority(p_ddraw->mt.tid[0], TSK_THREAD_PRIORITY_TIME_CRITICAL);
+ }
#endif /* DDRAW_MT */
#endif /* DDRAW_HIGH_PRIO_MEMCPY */
#if DDRAW_CPU_MONITOR || DDRAW_CPU_THROTTLING
- ret = tsk_timer_manager_start(p_ddraw->p_timer_mgr);
- if (ret == 0) {
- p_ddraw->cpu.id_timer = tsk_timer_manager_schedule(p_ddraw->p_timer_mgr, DDRAW_CPU_SCHEDULE_TIMEOUT, _tdav_producer_screencast_timer_cb, p_ddraw);
- }
- else {
- ret = 0; // not fatal error
- DDRAW_DEBUG_WARN("Failed to start CPU timer");
- }
+ ret = tsk_timer_manager_start(p_ddraw->p_timer_mgr);
+ if (ret == 0) {
+ p_ddraw->cpu.id_timer = tsk_timer_manager_schedule(p_ddraw->p_timer_mgr, DDRAW_CPU_SCHEDULE_TIMEOUT, _tdav_producer_screencast_timer_cb, p_ddraw);
+ }
+ else {
+ ret = 0; // not fatal error
+ DDRAW_DEBUG_WARN("Failed to start CPU timer");
+ }
#endif /* DDRAW_CPU_MONITOR || DDRAW_CPU_THROTTLING */
-bail:
- if (ret) {
- p_ddraw->b_started = tsk_false;
- if (p_ddraw->tid[0]) {
- tsk_thread_join(&(p_ddraw->tid[0]));
- }
+ bail:
+ if (ret) {
+ p_ddraw->b_started = tsk_false;
+ if (p_ddraw->tid[0]) {
+ tsk_thread_join(&(p_ddraw->tid[0]));
+ }
#if DDRAW_MT
- if (p_ddraw->mt.tid[0]) {
- tsk_thread_join(&(p_ddraw->mt.tid[0]));
- }
+ if (p_ddraw->mt.tid[0]) {
+ tsk_thread_join(&(p_ddraw->mt.tid[0]));
+ }
#endif /* DDRAW_MT */
- }
- ret = tsk_safeobj_unlock(p_ddraw);
+ }
+ ret = tsk_safeobj_unlock(p_ddraw);
- return ret;
+ return ret;
}
static int _tdav_producer_screencast_ddraw_pause(tmedia_producer_t* p_self)
{
- tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
+ tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
- if (!p_ddraw) {
- DDRAW_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_ddraw) {
+ DDRAW_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_ddraw);
+ tsk_safeobj_lock(p_ddraw);
- p_ddraw->b_paused = tsk_true;
- goto bail;
+ p_ddraw->b_paused = tsk_true;
+ goto bail;
-bail:
- tsk_safeobj_unlock(p_ddraw);
+ bail:
+ tsk_safeobj_unlock(p_ddraw);
- return 0;
+ return 0;
}
static int _tdav_producer_screencast_ddraw_stop(tmedia_producer_t* p_self)
{
- tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
+ tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)p_self;
- if (!p_ddraw) {
- DDRAW_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_ddraw) {
+ DDRAW_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_ddraw);
+ tsk_safeobj_lock(p_ddraw);
- if (!p_ddraw->b_started) {
- DDRAW_DEBUG_INFO("Already stopped");
- goto bail;
- }
+ if (!p_ddraw->b_started) {
+ DDRAW_DEBUG_INFO("Already stopped");
+ goto bail;
+ }
- p_ddraw->b_started = tsk_false;
- p_ddraw->b_paused = tsk_false;
+ p_ddraw->b_started = tsk_false;
+ p_ddraw->b_paused = tsk_false;
#if DDRAW_CPU_MONITOR || DDRAW_CPU_THROTTLING
- if (p_ddraw->p_timer_mgr) {
- tsk_timer_manager_stop(p_ddraw->p_timer_mgr);
- }
+ if (p_ddraw->p_timer_mgr) {
+ tsk_timer_manager_stop(p_ddraw->p_timer_mgr);
+ }
#endif /* DDRAW_CPU_MONITOR ||DDRAW_CPU_THROTTLING */
- // stop grabber thread
- if (p_ddraw->tid[0]) {
- tsk_thread_join(&(p_ddraw->tid[0]));
- }
+ // stop grabber thread
+ if (p_ddraw->tid[0]) {
+ tsk_thread_join(&(p_ddraw->tid[0]));
+ }
#if DDRAW_MT
- if (p_ddraw->mt.h_events[DDRAW_MT_EVENT_SHUTDOWN_INDEX]){
- SetEvent(p_ddraw->mt.h_events[DDRAW_MT_EVENT_SHUTDOWN_INDEX]);
- }
- if (p_ddraw->mt.tid[0]) {
- tsk_thread_join(&(p_ddraw->mt.tid[0]));
- }
- for (int i = 0; i < sizeof(p_ddraw->mt.h_events) / sizeof(p_ddraw->mt.h_events[0]); ++i) {
- if (p_ddraw->mt.h_events[i]) {
- CloseHandle(p_ddraw->mt.h_events[i]);
- p_ddraw->mt.h_events[i] = NULL;
- }
- }
+ if (p_ddraw->mt.h_events[DDRAW_MT_EVENT_SHUTDOWN_INDEX]) {
+ SetEvent(p_ddraw->mt.h_events[DDRAW_MT_EVENT_SHUTDOWN_INDEX]);
+ }
+ if (p_ddraw->mt.tid[0]) {
+ tsk_thread_join(&(p_ddraw->mt.tid[0]));
+ }
+ for (int i = 0; i < sizeof(p_ddraw->mt.h_events) / sizeof(p_ddraw->mt.h_events[0]); ++i) {
+ if (p_ddraw->mt.h_events[i]) {
+ CloseHandle(p_ddraw->mt.h_events[i]);
+ p_ddraw->mt.h_events[i] = NULL;
+ }
+ }
#endif
-bail:
- tsk_safeobj_unlock(p_ddraw);
+ bail:
+ tsk_safeobj_unlock(p_ddraw);
- return 0;
+ return 0;
}
static int _tdav_producer_screencast_grab(tdav_producer_screencast_ddraw_t* p_self)
{
- int ret = 0;
- HRESULT hr = S_OK;
- DDSURFACEDESC ddsd;
- DWORD nSizeWithoutPadding, nRowLengthInBytes, lockFlags;
- tmedia_producer_t* p_base = TMEDIA_PRODUCER(p_self);
- LPVOID lpBuffToSend, lpBuffYUV;
- BOOL bDirectMemSurfAccess = DDRAW_MEM_SURFACE_DIRECT_ACCESS;
+ int ret = 0;
+ HRESULT hr = S_OK;
+ DDSURFACEDESC ddsd;
+ DWORD nSizeWithoutPadding, nRowLengthInBytes, lockFlags;
+ tmedia_producer_t* p_base = TMEDIA_PRODUCER(p_self);
+ LPVOID lpBuffToSend, lpBuffYUV;
+ BOOL bDirectMemSurfAccess = DDRAW_MEM_SURFACE_DIRECT_ACCESS;
#if DDRAW_MT
- INT iMtFreeBuffIndex = -1;
+ INT iMtFreeBuffIndex = -1;
#endif
- //--uint64_t timeStart, timeEnd;
+ //--uint64_t timeStart, timeEnd;
- //--timeStart = tsk_time_now();
+ //--timeStart = tsk_time_now();
- if (!p_self) {
- DDRAW_CHECK_HR(hr = E_INVALIDARG);
- }
+ if (!p_self) {
+ DDRAW_CHECK_HR(hr = E_INVALIDARG);
+ }
- if (!p_self->b_started) {
+ if (!p_self->b_started) {
#if defined(E_ILLEGAL_METHOD_CALL)
- DDRAW_CHECK_HR(hr = E_ILLEGAL_METHOD_CALL);
+ DDRAW_CHECK_HR(hr = E_ILLEGAL_METHOD_CALL);
#else
- DDRAW_CHECK_HR(hr = E_FAIL);
+ DDRAW_CHECK_HR(hr = E_FAIL);
#endif
- }
+ }
#if DDRAW_MT
- {
- INT iIndex = 0;
- for (; (iIndex < DDRAW_MT_COUNT) && (p_self->mt.b_flags_array[iIndex] == TRUE); ++iIndex);
- if (iIndex == DDRAW_MT_COUNT) {
- goto bail;
- }
- }
+ {
+ INT iIndex = 0;
+ for (; (iIndex < DDRAW_MT_COUNT) && (p_self->mt.b_flags_array[iIndex] == TRUE); ++iIndex);
+ if (iIndex == DDRAW_MT_COUNT) {
+ goto bail;
+ }
+ }
#endif /* DDRAW_MT */
- if (p_self->p_surf_primary->IsLost() == DDERR_SURFACELOST) {
- DDRAW_CHECK_HR(hr = p_self->p_surf_primary->Restore());
- }
+ if (p_self->p_surf_primary->IsLost() == DDERR_SURFACELOST) {
+ DDRAW_CHECK_HR(hr = p_self->p_surf_primary->Restore());
+ }
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT;
- lockFlags = DDLOCK_READONLY |
+ ddsd.dwSize = sizeof(ddsd);
+ ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT;
+ lockFlags = DDLOCK_READONLY |
#if TDAV_UNDER_WINDOWS_CE
- // This flag has a slightly different name under Windows CE vs. Desktop, but it's the same behavior.
- DDLOCK_WAITNOTBUSY;
+ // This flag has a slightly different name under Windows CE vs. Desktop, but it's the same behavior.
+ DDLOCK_WAITNOTBUSY;
#else
- DDLOCK_WAIT;
+ DDLOCK_WAIT;
#endif
- DDRAW_CHECK_HR(hr = p_self->p_surf_primary->Lock(NULL, &ddsd, lockFlags, NULL));
- // make sure surface size and number of bits per pixel haven't changed
- if (TMEDIA_PRODUCER(p_self)->video.width != ddsd.dwWidth || TMEDIA_PRODUCER(p_self)->video.height != ddsd.dwHeight || p_self->n_buff_rgb_bitscount != ddsd.ddpfPixelFormat.dwRGBBitCount) {
- tsk_size_t n_buff_rgb_new;
- tmedia_chroma_t chroma_new;
- DDRAW_DEBUG_WARN("surface has changed: width %d<>%d or height %d<>%d or rgb_bits_count %d<>%d",
- p_base->video.width, ddsd.dwWidth,
- p_base->video.height, ddsd.dwHeight,
- p_self->n_buff_rgb_bitscount, ddsd.ddpfPixelFormat.dwRGBBitCount);
- if ((chroma_new = _tdav_producer_screencast_get_chroma(&ddsd.ddpfPixelFormat)) == tmedia_chroma_none) {
- DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
- }
- // allocate RGB buffer
- n_buff_rgb_new = (ddsd.dwWidth * ddsd.dwHeight * (ddsd.ddpfPixelFormat.dwRGBBitCount >> 3));
- if (p_self->n_buff_rgb < n_buff_rgb_new) {
- hr = _tdav_producer_screencast_alloc_rgb_buff(p_self, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount);
- if (FAILED(hr)) {
- p_self->p_surf_primary->Unlock(NULL); // unlock before going to bail
- DDRAW_CHECK_HR(hr);
- }
- }
- p_base->video.width = ddsd.dwWidth;
- p_base->video.height = ddsd.dwHeight;
- p_base->video.chroma = chroma_new;
- p_self->n_buff_rgb_bitscount = ddsd.ddpfPixelFormat.dwRGBBitCount;
- // Check if we can use built-in chroma conversion
+ DDRAW_CHECK_HR(hr = p_self->p_surf_primary->Lock(NULL, &ddsd, lockFlags, NULL));
+ // make sure surface size and number of bits per pixel haven't changed
+ if (TMEDIA_PRODUCER(p_self)->video.width != ddsd.dwWidth || TMEDIA_PRODUCER(p_self)->video.height != ddsd.dwHeight || p_self->n_buff_rgb_bitscount != ddsd.ddpfPixelFormat.dwRGBBitCount) {
+ tsk_size_t n_buff_rgb_new;
+ tmedia_chroma_t chroma_new;
+ DDRAW_DEBUG_WARN("surface has changed: width %d<>%d or height %d<>%d or rgb_bits_count %d<>%d",
+ p_base->video.width, ddsd.dwWidth,
+ p_base->video.height, ddsd.dwHeight,
+ p_self->n_buff_rgb_bitscount, ddsd.ddpfPixelFormat.dwRGBBitCount);
+ if ((chroma_new = _tdav_producer_screencast_get_chroma(&ddsd.ddpfPixelFormat)) == tmedia_chroma_none) {
+ DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
+ }
+ // allocate RGB buffer
+ n_buff_rgb_new = (ddsd.dwWidth * ddsd.dwHeight * (ddsd.ddpfPixelFormat.dwRGBBitCount >> 3));
+ if (p_self->n_buff_rgb < n_buff_rgb_new) {
+ hr = _tdav_producer_screencast_alloc_rgb_buff(p_self, ddsd.dwWidth, ddsd.dwHeight, ddsd.ddpfPixelFormat.dwRGBBitCount);
+ if (FAILED(hr)) {
+ p_self->p_surf_primary->Unlock(NULL); // unlock before going to bail
+ DDRAW_CHECK_HR(hr);
+ }
+ }
+ p_base->video.width = ddsd.dwWidth;
+ p_base->video.height = ddsd.dwHeight;
+ p_base->video.chroma = chroma_new;
+ p_self->n_buff_rgb_bitscount = ddsd.ddpfPixelFormat.dwRGBBitCount;
+ // Check if we can use built-in chroma conversion
#if DDRAW_HAVE_RGB32_TO_I420_INTRIN || DDRAW_HAVE_RGB32_TO_I420_ASM
- p_self->b_have_rgb32_conv =
- _tdav_producer_screencast_have_ssse3() // SSSE3 supported
- && DDRAW_IS_ALIGNED(p_base->video.width, DDRAW_MEM_ALIGNMENT) // width multiple of 16
- /* && DDRAW_IS_ALIGNED(p_base->video.height, DDRAW_MEM_ALIGNMENT) // height multiple of 16 */
- && p_base->video.chroma == tmedia_chroma_rgb32; // Primary screen RGB32
- if (p_self->b_have_rgb32_conv) {
- p_base->video.chroma = tmedia_chroma_yuv420p;
- }
+ p_self->b_have_rgb32_conv =
+ _tdav_producer_screencast_have_ssse3() // SSSE3 supported
+ && DDRAW_IS_ALIGNED(p_base->video.width, DDRAW_MEM_ALIGNMENT) // width multiple of 16
+ /* && DDRAW_IS_ALIGNED(p_base->video.height, DDRAW_MEM_ALIGNMENT) // height multiple of 16 */
+ && p_base->video.chroma == tmedia_chroma_rgb32; // Primary screen RGB32
+ if (p_self->b_have_rgb32_conv) {
+ p_base->video.chroma = tmedia_chroma_yuv420p;
+ }
#endif
- DDRAW_DEBUG_INFO("RGB32 -> I420 conversion supported: %s", p_self->b_have_rgb32_conv ? "YES" : "NO");
- // allocate YUV buffer
- if (p_self->b_have_rgb32_conv) {
- hr = _tdav_producer_screencast_alloc_yuv_buff(p_self, (DWORD)p_base->video.width, (DWORD)p_base->video.height);
- if (FAILED(hr)) {
- p_self->p_surf_primary->Unlock(NULL); // unlock before going to bail
- DDRAW_CHECK_HR(hr);
- }
- }
- // preview
+ DDRAW_DEBUG_INFO("RGB32 -> I420 conversion supported: %s", p_self->b_have_rgb32_conv ? "YES" : "NO");
+ // allocate YUV buffer
+ if (p_self->b_have_rgb32_conv) {
+ hr = _tdav_producer_screencast_alloc_yuv_buff(p_self, (DWORD)p_base->video.width, (DWORD)p_base->video.height);
+ if (FAILED(hr)) {
+ p_self->p_surf_primary->Unlock(NULL); // unlock before going to bail
+ DDRAW_CHECK_HR(hr);
+ }
+ }
+ // preview
#if DDRAW_PREVIEW
- p_self->bi_preview.bmiHeader.biWidth = ddsd.dwWidth;
- p_self->bi_preview.bmiHeader.biHeight = ddsd.dwHeight;
- p_self->bi_preview.bmiHeader.biBitCount = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount;
- p_self->bi_preview.bmiHeader.biSizeImage = (p_self->bi_preview.bmiHeader.biWidth * p_self->bi_preview.bmiHeader.biHeight * (p_self->bi_preview.bmiHeader.biBitCount >> 3));
+ p_self->bi_preview.bmiHeader.biWidth = ddsd.dwWidth;
+ p_self->bi_preview.bmiHeader.biHeight = ddsd.dwHeight;
+ p_self->bi_preview.bmiHeader.biBitCount = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount;
+ p_self->bi_preview.bmiHeader.biSizeImage = (p_self->bi_preview.bmiHeader.biWidth * p_self->bi_preview.bmiHeader.biHeight * (p_self->bi_preview.bmiHeader.biBitCount >> 3));
#endif /* DDRAW_PREVIEW */
- }
- nRowLengthInBytes = ddsd.dwWidth * (ddsd.ddpfPixelFormat.dwRGBBitCount >> 3);
- nSizeWithoutPadding = ddsd.dwHeight * nRowLengthInBytes;
-
- // init lpBuffToSend
- if (DDRAW_MEM_SURFACE_DIRECT_ACCESS && ddsd.lPitch == nRowLengthInBytes && (!p_self->b_have_rgb32_conv || DDRAW_IS_ALIGNED(ddsd.lpSurface, DDRAW_MEM_ALIGNMENT))) {
- // no padding
- lpBuffToSend = ddsd.lpSurface;
- bDirectMemSurfAccess = TRUE;
- }
- else {
- // with padding or copy requested
- UINT8 *pSurfBuff = (UINT8 *)ddsd.lpSurface, *pNegBuff = (UINT8 *)p_self->p_buff_rgb_aligned;
- DWORD y;
- bDirectMemSurfAccess = FALSE;
- //--timeStart = tsk_time_now();
- if (ddsd.lPitch == nRowLengthInBytes) {
- // copy without padding padding
- const UINT8* src = pSurfBuff;
- UINT8* dst = (UINT8*)p_self->p_buff_rgb_aligned;
- if (DDRAW_IS_ALIGNED(src, 16) && (nSizeWithoutPadding & 15) == 0) {
+ }
+ nRowLengthInBytes = ddsd.dwWidth * (ddsd.ddpfPixelFormat.dwRGBBitCount >> 3);
+ nSizeWithoutPadding = ddsd.dwHeight * nRowLengthInBytes;
+
+ // init lpBuffToSend
+ if (DDRAW_MEM_SURFACE_DIRECT_ACCESS && ddsd.lPitch == nRowLengthInBytes && (!p_self->b_have_rgb32_conv || DDRAW_IS_ALIGNED(ddsd.lpSurface, DDRAW_MEM_ALIGNMENT))) {
+ // no padding
+ lpBuffToSend = ddsd.lpSurface;
+ bDirectMemSurfAccess = TRUE;
+ }
+ else {
+ // with padding or copy requested
+ UINT8 *pSurfBuff = (UINT8 *)ddsd.lpSurface, *pNegBuff = (UINT8 *)p_self->p_buff_rgb_aligned;
+ DWORD y;
+ bDirectMemSurfAccess = FALSE;
+ //--timeStart = tsk_time_now();
+ if (ddsd.lPitch == nRowLengthInBytes) {
+ // copy without padding padding
+ const UINT8* src = pSurfBuff;
+ UINT8* dst = (UINT8*)p_self->p_buff_rgb_aligned;
+ if (DDRAW_IS_ALIGNED(src, 16) && (nSizeWithoutPadding & 15) == 0) {
#if DDRAW_HAVE_RGB32_TO_I420_INTRIN || DDRAW_HAVE_RGB32_TO_I420_ASM
- if ((nSizeWithoutPadding & 127) == 0) {
- for (DWORD i = 0; i < nSizeWithoutPadding; i += 128, src += 128, dst += 128) {
+ if ((nSizeWithoutPadding & 127) == 0) {
+ for (DWORD i = 0; i < nSizeWithoutPadding; i += 128, src += 128, dst += 128) {
#if defined(DDRAW_COPY128_ASM)
- DDRAW_COPY128_ASM(dst, src);
+ DDRAW_COPY128_ASM(dst, src);
#else
- DDRAW_COPY128_INTRIN(dst, src);
+ DDRAW_COPY128_INTRIN(dst, src);
#endif /* DDRAW_COPY128_ASM */
- }
- }
- else if((nSizeWithoutPadding & 63) == 0) {
- for (DWORD i = 0; i < nSizeWithoutPadding; i += 64, src += 64, dst += 64) {
+ }
+ }
+ else if((nSizeWithoutPadding & 63) == 0) {
+ for (DWORD i = 0; i < nSizeWithoutPadding; i += 64, src += 64, dst += 64) {
#if defined(DDRAW_COPY64_ASM)
- DDRAW_COPY64_ASM(dst, src);
+ DDRAW_COPY64_ASM(dst, src);
#else
- DDRAW_COPY64_INTRIN(dst, src);
+ DDRAW_COPY64_INTRIN(dst, src);
#endif /* DDRAW_COPY64_ASM */
- }
- }
- else { // (nSizeWithoutPadding & 15) == 0
- for (DWORD i = 0; i < nSizeWithoutPadding; i += 16, src += 16, dst += 16) {
+ }
+ }
+ else { // (nSizeWithoutPadding & 15) == 0
+ for (DWORD i = 0; i < nSizeWithoutPadding; i += 16, src += 16, dst += 16) {
#if defined(DDRAW_COPY16_ASM)
- DDRAW_COPY16_ASM(dst, src);
+ DDRAW_COPY16_ASM(dst, src);
#else
- DDRAW_COPY16_INTRIN(dst, src);
+ DDRAW_COPY16_INTRIN(dst, src);
#endif /* DDRAW_COPY16_ASM */
- }
- }
+ }
+ }
#else // neither ASM nor INTRINSIC support
- CopyMemory(dst, src, nSizeWithoutPadding);
+ CopyMemory(dst, src, nSizeWithoutPadding);
#endif /* DDRAW_HAVE_RGB32_TO_I420_INTRIN || DDRAW_HAVE_RGB32_TO_I420_ASM */
- }
- else { // not 16bytes aligned
- CopyMemory(dst, src, nSizeWithoutPadding);
- }
- }
- else {
- // copy with padding padding
- for (y = 0; y < ddsd.dwHeight; ++y) {
- CopyMemory(pNegBuff, pSurfBuff, nRowLengthInBytes);
- pSurfBuff += ddsd.lPitch;
- pNegBuff += nRowLengthInBytes;
- }
- }
- lpBuffToSend = p_self->p_buff_rgb_aligned;
- //--timeEnd = tsk_time_now();
- //--DDRAW_DEBUG_INFO("Mem copy: start=%llu, end=%llu, duration=%llu", timeStart, timeEnd, (timeEnd - timeStart));
- }
- if (!bDirectMemSurfAccess) {
- // surface buffer no longer needed, unlock
- DDRAW_CHECK_HR(hr = p_self->p_surf_primary->Unlock(NULL));
- }
- // display preview
+ }
+ else { // not 16bytes aligned
+ CopyMemory(dst, src, nSizeWithoutPadding);
+ }
+ }
+ else {
+ // copy with padding padding
+ for (y = 0; y < ddsd.dwHeight; ++y) {
+ CopyMemory(pNegBuff, pSurfBuff, nRowLengthInBytes);
+ pSurfBuff += ddsd.lPitch;
+ pNegBuff += nRowLengthInBytes;
+ }
+ }
+ lpBuffToSend = p_self->p_buff_rgb_aligned;
+ //--timeEnd = tsk_time_now();
+ //--DDRAW_DEBUG_INFO("Mem copy: start=%llu, end=%llu, duration=%llu", timeStart, timeEnd, (timeEnd - timeStart));
+ }
+ if (!bDirectMemSurfAccess) {
+ // surface buffer no longer needed, unlock
+ DDRAW_CHECK_HR(hr = p_self->p_surf_primary->Unlock(NULL));
+ }
+ // display preview
#if DDRAW_PREVIEW
- if (p_self->hwnd_preview) {
- HWND hWnd; // copy for thread-safeness
- HDC hDC = GetDC((hWnd = p_self->hwnd_preview));
- if (hDC) {
- RECT rcPreview;
- if (GetWindowRect(hWnd, &rcPreview)) {
- LONG nPreviewWidth = (rcPreview.right - rcPreview.left);
- LONG nPreviewHeight = (rcPreview.bottom - rcPreview.top);
- StretchDIBits(
- hDC,
- 0, 0, nPreviewWidth, nPreviewHeight,
- 0, 0, p_self->bi_preview.bmiHeader.biWidth, p_self->bi_preview.bmiHeader.biHeight,
- lpBuffToSend,
- &p_self->bi_preview,
- DIB_RGB_COLORS,
- SRCCOPY);
- }
- ReleaseDC(hWnd, hDC);
- }
- }
+ if (p_self->hwnd_preview) {
+ HWND hWnd; // copy for thread-safeness
+ HDC hDC = GetDC((hWnd = p_self->hwnd_preview));
+ if (hDC) {
+ RECT rcPreview;
+ if (GetWindowRect(hWnd, &rcPreview)) {
+ LONG nPreviewWidth = (rcPreview.right - rcPreview.left);
+ LONG nPreviewHeight = (rcPreview.bottom - rcPreview.top);
+ StretchDIBits(
+ hDC,
+ 0, 0, nPreviewWidth, nPreviewHeight,
+ 0, 0, p_self->bi_preview.bmiHeader.biWidth, p_self->bi_preview.bmiHeader.biHeight,
+ lpBuffToSend,
+ &p_self->bi_preview,
+ DIB_RGB_COLORS,
+ SRCCOPY);
+ }
+ ReleaseDC(hWnd, hDC);
+ }
+ }
#endif /* DDRAW_PREVIEW */
- // check we have a free buffer
+ // check we have a free buffer
#if DDRAW_MT
- {
- for (INT iIndex = 0; iIndex < DDRAW_MT_COUNT; ++iIndex) {
- if (p_self->mt.b_flags_array[iIndex] != TRUE) {
- iMtFreeBuffIndex = iIndex;
- lpBuffYUV = p_self->mt.p_buff_yuv_aligned_array[iIndex];
- break;
- }
- }
- if (iMtFreeBuffIndex < 0) {
- lpBuffToSend = NULL; // do not waste time converting or encoding
- lpBuffYUV = NULL;
- }
- }
+ {
+ for (INT iIndex = 0; iIndex < DDRAW_MT_COUNT; ++iIndex) {
+ if (p_self->mt.b_flags_array[iIndex] != TRUE) {
+ iMtFreeBuffIndex = iIndex;
+ lpBuffYUV = p_self->mt.p_buff_yuv_aligned_array[iIndex];
+ break;
+ }
+ }
+ if (iMtFreeBuffIndex < 0) {
+ lpBuffToSend = NULL; // do not waste time converting or encoding
+ lpBuffYUV = NULL;
+ }
+ }
#else
- lpBuffYUV = p_self->p_buff_yuv_aligned;
+ lpBuffYUV = p_self->p_buff_yuv_aligned;
#endif /* DDRAW_MT */
- //--timeStart = tsk_time_now();
- if (lpBuffToSend && (lpBuffYUV || !p_self->b_have_rgb32_conv)) {
- if (p_self->b_have_rgb32_conv) {
- // Convert from RGB32 to I420
+ //--timeStart = tsk_time_now();
+ if (lpBuffToSend && (lpBuffYUV || !p_self->b_have_rgb32_conv)) {
+ if (p_self->b_have_rgb32_conv) {
+ // Convert from RGB32 to I420
#if DDRAW_HAVE_RGB32_TO_I420_ASM
- _tdav_producer_screencast_rgb32_to_yuv420_asm_ssse3((uint8_t*)lpBuffYUV, (const uint8_t*)lpBuffToSend, (int)p_base->video.width, (int)p_base->video.height);
+ _tdav_producer_screencast_rgb32_to_yuv420_asm_ssse3((uint8_t*)lpBuffYUV, (const uint8_t*)lpBuffToSend, (int)p_base->video.width, (int)p_base->video.height);
#elif DDRAW_HAVE_RGB32_TO_I420_INTRIN
- _tdav_producer_screencast_rgb32_to_yuv420_intrin_ssse3((uint8_t*)lpBuffYUV, (const uint8_t*)lpBuffToSend, (int)p_base->video.width, (int)p_base->video.height);
+ _tdav_producer_screencast_rgb32_to_yuv420_intrin_ssse3((uint8_t*)lpBuffYUV, (const uint8_t*)lpBuffToSend, (int)p_base->video.width, (int)p_base->video.height);
#else
- DDRAW_CHECK_HR(hr = E_NOTIMPL); // never called
+ DDRAW_CHECK_HR(hr = E_NOTIMPL); // never called
#endif
#if DDRAW_MT
- p_self->mt.b_flags_array[iMtFreeBuffIndex] = TRUE;
- if (!SetEvent(p_self->mt.h_events[iMtFreeBuffIndex])) {
- DDRAW_CHECK_HR(hr = E_FAIL);
- }
+ p_self->mt.b_flags_array[iMtFreeBuffIndex] = TRUE;
+ if (!SetEvent(p_self->mt.h_events[iMtFreeBuffIndex])) {
+ DDRAW_CHECK_HR(hr = E_FAIL);
+ }
#else
- p_base->enc_cb.callback(p_base->enc_cb.callback_data, lpBuffYUV, p_self->n_buff_yuv);
+ p_base->enc_cb.callback(p_base->enc_cb.callback_data, lpBuffYUV, p_self->n_buff_yuv);
#endif
- }
- else {
- // Send RGB32 buffer to the encode callback and let conversion be done by libyuv
- // do not multi-thread as we cannot perform chroma conversion and encoding in parallel
- p_base->enc_cb.callback(p_base->enc_cb.callback_data, lpBuffToSend, nSizeWithoutPadding);
- }
- }
- //--timeEnd = tsk_time_now();
- //--DDRAW_DEBUG_INFO("Encode callback: start=%llu, end=%llu, duration=%llu", timeStart, timeEnd, (timeEnd - timeStart));
-
- if (bDirectMemSurfAccess) {
- // surface buffer was used in preview and encode callback, unlock now
- DDRAW_CHECK_HR(hr = p_self->p_surf_primary->Unlock(NULL));
- }
+ }
+ else {
+ // Send RGB32 buffer to the encode callback and let conversion be done by libyuv
+ // do not multi-thread as we cannot perform chroma conversion and encoding in parallel
+ p_base->enc_cb.callback(p_base->enc_cb.callback_data, lpBuffToSend, nSizeWithoutPadding);
+ }
+ }
+ //--timeEnd = tsk_time_now();
+ //--DDRAW_DEBUG_INFO("Encode callback: start=%llu, end=%llu, duration=%llu", timeStart, timeEnd, (timeEnd - timeStart));
-bail:
- if (hr == DDERR_SURFACELOST) {
- /*hr = */p_self->p_surf_primary->Restore();
- hr = S_OK;
- }
+ if (bDirectMemSurfAccess) {
+ // surface buffer was used in preview and encode callback, unlock now
+ DDRAW_CHECK_HR(hr = p_self->p_surf_primary->Unlock(NULL));
+ }
- //--timeEnd = tsk_time_now();
- //--DDRAW_DEBUG_INFO("Grab and encode duration=%llu", (timeEnd - timeStart));
+ bail:
+ if (hr == DDERR_SURFACELOST) {
+ /*hr = */p_self->p_surf_primary->Restore();
+ hr = S_OK;
+ }
+
+ //--timeEnd = tsk_time_now();
+ //--DDRAW_DEBUG_INFO("Grab and encode duration=%llu", (timeEnd - timeStart));
- return SUCCEEDED(hr) ? 0 : -1;
+ return SUCCEEDED(hr) ? 0 : -1;
}
static tmedia_chroma_t _tdav_producer_screencast_get_chroma(const DDPIXELFORMAT* pixelFormat)
{
- HRESULT hr = DD_OK;
- if (pixelFormat->dwFlags != DDPF_RGB) {
- DDRAW_DEBUG_ERROR("dwFlags(%d) != DDPF_RGB", pixelFormat->dwFlags);
- DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
- }
- switch (pixelFormat->dwRGBBitCount) {
- case 32: // RGB32
- case 24: // RGB24
- // pixels must be aligned for fast copy
- if (pixelFormat->dwRBitMask != 0xff0000 || pixelFormat->dwGBitMask != 0xff00 || pixelFormat->dwBBitMask != 0xff || pixelFormat->dwRGBAlphaBitMask != 0) {
- DDRAW_DEBUG_ERROR("Pixels not aligned");
- }
- return pixelFormat->dwRGBBitCount == 24 ? tmedia_chroma_bgr24 : tmedia_chroma_rgb32;
- case 16: // RGB565
- // pixels must be aligned for fast copy
- if (pixelFormat->dwRBitMask != 0xF800 || pixelFormat->dwGBitMask != 0x7E0 || pixelFormat->dwBBitMask != 0x1F) {
- DDRAW_DEBUG_ERROR("Pixels not aligned");
- }
- return tmedia_chroma_rgb565le;
- default:
- DDRAW_DEBUG_ERROR("dwRGBBitCount(%d) != 24 and 32", pixelFormat->dwRGBBitCount);
- DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
- break;
- }
+ HRESULT hr = DD_OK;
+ if (pixelFormat->dwFlags != DDPF_RGB) {
+ DDRAW_DEBUG_ERROR("dwFlags(%d) != DDPF_RGB", pixelFormat->dwFlags);
+ DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
+ }
+ switch (pixelFormat->dwRGBBitCount) {
+ case 32: // RGB32
+ case 24: // RGB24
+ // pixels must be aligned for fast copy
+ if (pixelFormat->dwRBitMask != 0xff0000 || pixelFormat->dwGBitMask != 0xff00 || pixelFormat->dwBBitMask != 0xff || pixelFormat->dwRGBAlphaBitMask != 0) {
+ DDRAW_DEBUG_ERROR("Pixels not aligned");
+ }
+ return pixelFormat->dwRGBBitCount == 24 ? tmedia_chroma_bgr24 : tmedia_chroma_rgb32;
+ case 16: // RGB565
+ // pixels must be aligned for fast copy
+ if (pixelFormat->dwRBitMask != 0xF800 || pixelFormat->dwGBitMask != 0x7E0 || pixelFormat->dwBBitMask != 0x1F) {
+ DDRAW_DEBUG_ERROR("Pixels not aligned");
+ }
+ return tmedia_chroma_rgb565le;
+ default:
+ DDRAW_DEBUG_ERROR("dwRGBBitCount(%d) != 24 and 32", pixelFormat->dwRGBBitCount);
+ DDRAW_CHECK_HR(hr = DDERR_INVALIDCAPS);
+ break;
+ }
-bail:
- return tmedia_chroma_none;
+ bail:
+ return tmedia_chroma_none;
}
static HRESULT _tdav_producer_screencast_create_module(LPDDrawModule lpModule)
{
- typedef HRESULT (WINAPI *pDirectDrawCreateFunc)(_In_ GUID FAR *lpGUID,
- _Out_ LPDIRECTDRAW FAR *lplpDD,
- _In_ IUnknown FAR *pUnkOuter);
- HRESULT hr = S_OK;
- pDirectDrawCreateFunc DirectDrawCreate_ = NULL;
-
- if (!lpModule) {
- DDRAW_CHECK_HR(hr = E_INVALIDARG);
- }
+ typedef HRESULT (WINAPI *pDirectDrawCreateFunc)(_In_ GUID FAR *lpGUID,
+ _Out_ LPDIRECTDRAW FAR *lplpDD,
+ _In_ IUnknown FAR *pUnkOuter);
+ HRESULT hr = S_OK;
+ pDirectDrawCreateFunc DirectDrawCreate_ = NULL;
+
+ if (!lpModule) {
+ DDRAW_CHECK_HR(hr = E_INVALIDARG);
+ }
- if (!lpModule->hDLL && !(lpModule->hDLL = LoadLibrary(TEXT("ddraw.dll")))) {
- DDRAW_DEBUG_ERROR("Failed to load ddraw.dll: %d", GetLastError());
- DDRAW_CHECK_HR(hr = E_FAIL);
- }
- if (!lpModule->lpDD) {
- // Hum, "GetProcAddressA" is missing but ""GetProcAddressW" exists on CE
+ if (!lpModule->hDLL && !(lpModule->hDLL = LoadLibrary(TEXT("ddraw.dll")))) {
+ DDRAW_DEBUG_ERROR("Failed to load ddraw.dll: %d", GetLastError());
+ DDRAW_CHECK_HR(hr = E_FAIL);
+ }
+ if (!lpModule->lpDD) {
+ // Hum, "GetProcAddressA" is missing but ""GetProcAddressW" exists on CE
#if TDAV_UNDER_WINDOWS_CE
# define DirectDrawCreateName TEXT("DirectDrawCreate")
#else
# define DirectDrawCreateName "DirectDrawCreate"
#endif
- if (!(DirectDrawCreate_ = (pDirectDrawCreateFunc)GetProcAddress(lpModule->hDLL, DirectDrawCreateName))) {
- DDRAW_DEBUG_ERROR("Failed to find DirectDrawCreate in ddraw.dll: %d", GetLastError());
- DDRAW_CHECK_HR(hr = E_FAIL);
- }
- DDRAW_CHECK_HR(hr = DirectDrawCreate_(NULL, &lpModule->lpDD, NULL));
- }
+ if (!(DirectDrawCreate_ = (pDirectDrawCreateFunc)GetProcAddress(lpModule->hDLL, DirectDrawCreateName))) {
+ DDRAW_DEBUG_ERROR("Failed to find DirectDrawCreate in ddraw.dll: %d", GetLastError());
+ DDRAW_CHECK_HR(hr = E_FAIL);
+ }
+ DDRAW_CHECK_HR(hr = DirectDrawCreate_(NULL, &lpModule->lpDD, NULL));
+ }
-bail:
- return hr;
+ bail:
+ return hr;
}
static HRESULT _tdav_producer_screencast_alloc_rgb_buff(tdav_producer_screencast_ddraw_t* p_ddraw, DWORD w, DWORD h, DWORD bitsCount)
{
- HRESULT hr = S_OK;
- DWORD n_buff_rgb_new = (w * h * (bitsCount >> 3));
-
- if (p_ddraw->n_buff_rgb < n_buff_rgb_new) {
- p_ddraw->p_buff_rgb_aligned = tsk_realloc_aligned(p_ddraw->p_buff_rgb_aligned, n_buff_rgb_new, DDRAW_MEM_ALIGNMENT);
- if (!p_ddraw->p_buff_rgb_aligned) {
- p_ddraw->n_buff_rgb = 0;
- DDRAW_CHECK_HR(hr = DDERR_OUTOFMEMORY);
- }
- p_ddraw->n_buff_rgb = n_buff_rgb_new;
- }
+ HRESULT hr = S_OK;
+ DWORD n_buff_rgb_new = (w * h * (bitsCount >> 3));
+
+ if (p_ddraw->n_buff_rgb < n_buff_rgb_new) {
+ p_ddraw->p_buff_rgb_aligned = tsk_realloc_aligned(p_ddraw->p_buff_rgb_aligned, n_buff_rgb_new, DDRAW_MEM_ALIGNMENT);
+ if (!p_ddraw->p_buff_rgb_aligned) {
+ p_ddraw->n_buff_rgb = 0;
+ DDRAW_CHECK_HR(hr = DDERR_OUTOFMEMORY);
+ }
+ p_ddraw->n_buff_rgb = n_buff_rgb_new;
+ }
-bail:
- return hr;
+ bail:
+ return hr;
}
static HRESULT _tdav_producer_screencast_alloc_yuv_buff(tdav_producer_screencast_ddraw_t* p_ddraw, DWORD w, DWORD h)
{
- HRESULT hr = S_OK;
- void** pp_buff_yuv_aligned;
- int n_buff_yuv_aligned_count;
+ HRESULT hr = S_OK;
+ void** pp_buff_yuv_aligned;
+ int n_buff_yuv_aligned_count;
#if DDRAW_MT
- pp_buff_yuv_aligned = p_ddraw->mt.p_buff_yuv_aligned_array;
- n_buff_yuv_aligned_count = sizeof(p_ddraw->mt.p_buff_yuv_aligned_array)/sizeof(p_ddraw->mt.p_buff_yuv_aligned_array[0]);
+ pp_buff_yuv_aligned = p_ddraw->mt.p_buff_yuv_aligned_array;
+ n_buff_yuv_aligned_count = sizeof(p_ddraw->mt.p_buff_yuv_aligned_array)/sizeof(p_ddraw->mt.p_buff_yuv_aligned_array[0]);
#else
- pp_buff_yuv_aligned = &p_ddraw->p_buff_yuv_aligned;
- n_buff_yuv_aligned_count = 1;
+ pp_buff_yuv_aligned = &p_ddraw->p_buff_yuv_aligned;
+ n_buff_yuv_aligned_count = 1;
#endif /* DDRAW_MT */
- p_ddraw->n_buff_yuv = (w * h * 3) >> 1;
- for (int i = 0; i < n_buff_yuv_aligned_count; ++i) {
- pp_buff_yuv_aligned[i] = tsk_realloc_aligned(pp_buff_yuv_aligned[i], p_ddraw->n_buff_yuv, DDRAW_MEM_ALIGNMENT);
- if (!pp_buff_yuv_aligned[i]) {
- p_ddraw->n_buff_yuv = 0;
- DDRAW_CHECK_HR(hr = DDERR_OUTOFMEMORY);
- }
- }
+ p_ddraw->n_buff_yuv = (w * h * 3) >> 1;
+ for (int i = 0; i < n_buff_yuv_aligned_count; ++i) {
+ pp_buff_yuv_aligned[i] = tsk_realloc_aligned(pp_buff_yuv_aligned[i], p_ddraw->n_buff_yuv, DDRAW_MEM_ALIGNMENT);
+ if (!pp_buff_yuv_aligned[i]) {
+ p_ddraw->n_buff_yuv = 0;
+ DDRAW_CHECK_HR(hr = DDERR_OUTOFMEMORY);
+ }
+ }
-bail:
- return hr;
+ bail:
+ return hr;
}
static void* TSK_STDCALL _tdav_producer_screencast_grap_thread(void *arg)
{
- tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)arg;
- tmedia_producer_t* p_base = TMEDIA_PRODUCER(arg);
- int ret = 0;
+ tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)arg;
+ tmedia_producer_t* p_base = TMEDIA_PRODUCER(arg);
+ int ret = 0;
- // FPS manager
- uint64_t TimeNow, TimeLastFrame = 0;
- uint64_t TimeFrameDuration = (1000 / p_base->video.fps);
+ // FPS manager
+ uint64_t TimeNow, TimeLastFrame = 0;
+ uint64_t TimeFrameDuration = (1000 / p_base->video.fps);
- DDRAW_DEBUG_INFO("Grab thread -- START");
+ DDRAW_DEBUG_INFO("Grab thread -- START");
- while (ret == 0 && p_ddraw->b_started) {
+ while (ret == 0 && p_ddraw->b_started) {
#if DDRAW_CPU_THROTTLING
- TimeFrameDuration = (1000 / p_ddraw->cpu.fps_target);
+ TimeFrameDuration = (1000 / p_ddraw->cpu.fps_target);
#endif /* DDRAW_CPU_THROTTLING */
- TimeNow = tsk_time_now();
- if ((TimeNow - TimeLastFrame) > TimeFrameDuration) {
- if (!p_ddraw->b_muted && !p_ddraw->b_paused) {
- if (ret = _tdav_producer_screencast_grab(p_ddraw)) {
- goto next;
- }
- }
- TimeLastFrame = TimeNow;
- }
- else {
- tsk_thread_sleep(1);
+ TimeNow = tsk_time_now();
+ if ((TimeNow - TimeLastFrame) > TimeFrameDuration) {
+ if (!p_ddraw->b_muted && !p_ddraw->b_paused) {
+ if (ret = _tdav_producer_screencast_grab(p_ddraw)) {
+ goto next;
+ }
+ }
+ TimeLastFrame = TimeNow;
+ }
+ else {
+ tsk_thread_sleep(1);
#if 0
- DDRAW_DEBUG_INFO("Skip frame");
+ DDRAW_DEBUG_INFO("Skip frame");
#endif
- }
- next:
- ;
- }
- DDRAW_DEBUG_INFO("Grab thread -- STOP");
- return tsk_null;
+ }
+ next:
+ ;
+ }
+ DDRAW_DEBUG_INFO("Grab thread -- STOP");
+ return tsk_null;
}
#if DDRAW_MT
static void* TSK_STDCALL _tdav_producer_screencast_mt_encode_thread(void *arg)
{
- tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)arg;
- tmedia_producer_t* p_base = TMEDIA_PRODUCER(arg);
- DWORD dwEvent, dwIndex;
- int ret = 0;
- DWORD events_count = sizeof(p_ddraw->mt.h_events) / sizeof(p_ddraw->mt.h_events[0]);
-
- DDRAW_DEBUG_INFO("Encode MT thread -- START");
-
- while (ret == 0 && p_ddraw->b_started) {
- dwEvent = WaitForMultipleObjects(events_count, p_ddraw->mt.h_events, FALSE, INFINITE);
- if (!p_ddraw->b_started) {
- break;
- }
- if (dwEvent < WAIT_OBJECT_0 || dwEvent >(WAIT_OBJECT_0 + events_count)) {
- DDRAW_DEBUG_ERROR("Invalid dwEvent(%d)", dwEvent);
- break;
- }
- dwIndex = (dwEvent - WAIT_OBJECT_0);
- if (p_ddraw->mt.b_flags_array[dwIndex] != TRUE) {
- // must never happen
- DDRAW_DEBUG_ERROR("Invalid b_flags_array(%d)", dwIndex);
- break;
- }
-
- p_base->enc_cb.callback(p_base->enc_cb.callback_data, p_ddraw->mt.p_buff_yuv_aligned_array[dwIndex], p_ddraw->n_buff_yuv);
- p_ddraw->mt.b_flags_array[dwIndex] = FALSE;
- }
- DDRAW_DEBUG_INFO("Encode MT -- STOP");
- return tsk_null;
+ tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)arg;
+ tmedia_producer_t* p_base = TMEDIA_PRODUCER(arg);
+ DWORD dwEvent, dwIndex;
+ int ret = 0;
+ DWORD events_count = sizeof(p_ddraw->mt.h_events) / sizeof(p_ddraw->mt.h_events[0]);
+
+ DDRAW_DEBUG_INFO("Encode MT thread -- START");
+
+ while (ret == 0 && p_ddraw->b_started) {
+ dwEvent = WaitForMultipleObjects(events_count, p_ddraw->mt.h_events, FALSE, INFINITE);
+ if (!p_ddraw->b_started) {
+ break;
+ }
+ if (dwEvent < WAIT_OBJECT_0 || dwEvent >(WAIT_OBJECT_0 + events_count)) {
+ DDRAW_DEBUG_ERROR("Invalid dwEvent(%d)", dwEvent);
+ break;
+ }
+ dwIndex = (dwEvent - WAIT_OBJECT_0);
+ if (p_ddraw->mt.b_flags_array[dwIndex] != TRUE) {
+ // must never happen
+ DDRAW_DEBUG_ERROR("Invalid b_flags_array(%d)", dwIndex);
+ break;
+ }
+
+ p_base->enc_cb.callback(p_base->enc_cb.callback_data, p_ddraw->mt.p_buff_yuv_aligned_array[dwIndex], p_ddraw->n_buff_yuv);
+ p_ddraw->mt.b_flags_array[dwIndex] = FALSE;
+ }
+ DDRAW_DEBUG_INFO("Encode MT -- STOP");
+ return tsk_null;
}
#endif /* DDRAW_MT */
#if DDRAW_CPU_MONITOR || DDRAW_CPU_THROTTLING
static unsigned long long FileTimeToInt64(const FILETIME & ft)
{
- return (((unsigned long long)(ft.dwHighDateTime))<<32) | ((unsigned long long)ft.dwLowDateTime);
+ return (((unsigned long long)(ft.dwHighDateTime))<<32) | ((unsigned long long)ft.dwLowDateTime);
}
static BOOL GetCpuPercents(unsigned long long* PercentIdle, unsigned long long* PercentUsage)
{
- static unsigned long long _prevTicks = 0;
- static unsigned long long _prevIdleTime = 0;
- unsigned long long ticks, idleTime;
- BOOL bSaveValues = FALSE, bSet = FALSE;
+ static unsigned long long _prevTicks = 0;
+ static unsigned long long _prevIdleTime = 0;
+ unsigned long long ticks, idleTime;
+ BOOL bSaveValues = FALSE, bSet = FALSE;
#if TDAV_UNDER_WINDOWS_CE
- bSaveValues = TRUE;
- ticks = GetTickCount();
- idleTime = GetIdleTime();
+ bSaveValues = TRUE;
+ ticks = GetTickCount();
+ idleTime = GetIdleTime();
#else
- {
- FILETIME _idleTime, _kernelTime, _userTime;
- if (GetSystemTimes(&_idleTime, &_kernelTime, &_userTime)) {
- idleTime = FileTimeToInt64(_idleTime);
- ticks = FileTimeToInt64(_kernelTime) + FileTimeToInt64(_userTime);
- bSaveValues = TRUE;
- }
- }
+ {
+ FILETIME _idleTime, _kernelTime, _userTime;
+ if (GetSystemTimes(&_idleTime, &_kernelTime, &_userTime)) {
+ idleTime = FileTimeToInt64(_idleTime);
+ ticks = FileTimeToInt64(_kernelTime) + FileTimeToInt64(_userTime);
+ bSaveValues = TRUE;
+ }
+ }
#endif
- if (_prevTicks > 0) {
- *PercentIdle = ((100 * (idleTime - _prevIdleTime)) / (ticks - _prevTicks));
- *PercentUsage = 100 - *PercentIdle;
- bSet = TRUE;
- }
- if (bSaveValues) {
- _prevTicks = ticks;
- _prevIdleTime = idleTime;
- }
+ if (_prevTicks > 0) {
+ *PercentIdle = ((100 * (idleTime - _prevIdleTime)) / (ticks - _prevTicks));
+ *PercentUsage = 100 - *PercentIdle;
+ bSet = TRUE;
+ }
+ if (bSaveValues) {
+ _prevTicks = ticks;
+ _prevIdleTime = idleTime;
+ }
- return bSet;
+ return bSet;
}
static int _tdav_producer_screencast_timer_cb(const void* arg, tsk_timer_id_t timer_id)
@@ -1420,36 +1416,36 @@ static int _tdav_producer_screencast_timer_cb(const void* arg, tsk_timer_id_t ti
tdav_producer_screencast_ddraw_t* p_ddraw = (tdav_producer_screencast_ddraw_t*)arg;
int ret = 0;
- if (!p_ddraw->b_started) {
- return 0;
- }
+ if (!p_ddraw->b_started) {
+ return 0;
+ }
if (p_ddraw->cpu.id_timer == timer_id) {
- unsigned long long PercentIdle, PercentUsage;
- if (GetCpuPercents(&PercentIdle, &PercentUsage) == TRUE) {
- TSK_DEBUG_INFO("\n\n****\n\nCPU Usage = %lld\n\n***", PercentUsage);
+ unsigned long long PercentIdle, PercentUsage;
+ if (GetCpuPercents(&PercentIdle, &PercentUsage) == TRUE) {
+ TSK_DEBUG_INFO("\n\n****\n\nCPU Usage = %lld\n\n***", PercentUsage);
#if DDRAW_CPU_THROTTLING
- {
- if ((PercentUsage + DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN) > DDRAW_CPU_THROTTLING_THRESHOLD) {
- unsigned long long NewTargetPercentUsage = TSK_CLAMP(DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN, DDRAW_CPU_THROTTLING_THRESHOLD - DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN, INT_MAX);
- int NewTargetFps = (int)((NewTargetPercentUsage * p_ddraw->cpu.fps_target) / PercentUsage);
- NewTargetFps = TSK_CLAMP(DDRAW_CPU_THROTTLING_FPS_MIN, NewTargetFps, TMEDIA_PRODUCER(p_ddraw)->video.fps);
- TSK_DEBUG_INFO("\n\n****\n\nCPU throttling = (%lld+%d)>%d, NewTargetPercentUsage=%lld, NewTargetFps=%d\n\n***",
- PercentUsage, DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN, DDRAW_CPU_THROTTLING_THRESHOLD, NewTargetPercentUsage, NewTargetFps);
- p_ddraw->cpu.fps_target = NewTargetFps;
- }
- else if (PercentUsage < DDRAW_CPU_THROTTLING_THRESHOLD) {
- if ((p_ddraw->cpu.fps_target + DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN) < TMEDIA_PRODUCER(p_ddraw)->video.fps) { // not honoring the negotiated fps yet?
- p_ddraw->cpu.fps_target += 1; // TODO: this is ok only if the timer timeout is set to 1s or less
- }
- }
- }
+ {
+ if ((PercentUsage + DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN) > DDRAW_CPU_THROTTLING_THRESHOLD) {
+ unsigned long long NewTargetPercentUsage = TSK_CLAMP(DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN, DDRAW_CPU_THROTTLING_THRESHOLD - DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN, INT_MAX);
+ int NewTargetFps = (int)((NewTargetPercentUsage * p_ddraw->cpu.fps_target) / PercentUsage);
+ NewTargetFps = TSK_CLAMP(DDRAW_CPU_THROTTLING_FPS_MIN, NewTargetFps, TMEDIA_PRODUCER(p_ddraw)->video.fps);
+ TSK_DEBUG_INFO("\n\n****\n\nCPU throttling = (%lld+%d)>%d, NewTargetPercentUsage=%lld, NewTargetFps=%d\n\n***",
+ PercentUsage, DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN, DDRAW_CPU_THROTTLING_THRESHOLD, NewTargetPercentUsage, NewTargetFps);
+ p_ddraw->cpu.fps_target = NewTargetFps;
+ }
+ else if (PercentUsage < DDRAW_CPU_THROTTLING_THRESHOLD) {
+ if ((p_ddraw->cpu.fps_target + DDRAW_CPU_THROTTLING_THRESHOLD_MARGIN) < TMEDIA_PRODUCER(p_ddraw)->video.fps) { // not honoring the negotiated fps yet?
+ p_ddraw->cpu.fps_target += 1; // TODO: this is ok only if the timer timeout is set to 1s or less
+ }
+ }
+ }
#endif /* DDRAW_CPU_THROTTLING */
- }
+ }
- if (p_ddraw->b_started) {
- p_ddraw->cpu.id_timer = tsk_timer_manager_schedule(p_ddraw->p_timer_mgr, DDRAW_CPU_SCHEDULE_TIMEOUT, _tdav_producer_screencast_timer_cb, p_ddraw);
- }
+ if (p_ddraw->b_started) {
+ p_ddraw->cpu.id_timer = tsk_timer_manager_schedule(p_ddraw->p_timer_mgr, DDRAW_CPU_SCHEDULE_TIMEOUT, _tdav_producer_screencast_timer_cb, p_ddraw);
+ }
}
return 0;
}
@@ -1462,80 +1458,78 @@ static int _tdav_producer_screencast_timer_cb(const void* arg, tsk_timer_id_t ti
/* constructor */
static tsk_object_t* _tdav_producer_screencast_ddraw_ctor(tsk_object_t *self, va_list * app)
{
- tdav_producer_screencast_ddraw_t *p_ddraw = (tdav_producer_screencast_ddraw_t *)self;
- if (p_ddraw) {
- /* init base */
- tmedia_producer_init(TMEDIA_PRODUCER(p_ddraw));
- TMEDIA_PRODUCER(p_ddraw)->video.chroma = tmedia_chroma_bgr24; // RGB24 on x86 (little endians) stored as BGR24
- /* init self with default values*/
- TMEDIA_PRODUCER(p_ddraw)->video.fps = 15;
- TMEDIA_PRODUCER(p_ddraw)->video.width = 352;
- TMEDIA_PRODUCER(p_ddraw)->video.height = 288;
-
- tsk_safeobj_init(p_ddraw);
- }
- return self;
+ tdav_producer_screencast_ddraw_t *p_ddraw = (tdav_producer_screencast_ddraw_t *)self;
+ if (p_ddraw) {
+ /* init base */
+ tmedia_producer_init(TMEDIA_PRODUCER(p_ddraw));
+ TMEDIA_PRODUCER(p_ddraw)->video.chroma = tmedia_chroma_bgr24; // RGB24 on x86 (little endians) stored as BGR24
+ /* init self with default values*/
+ TMEDIA_PRODUCER(p_ddraw)->video.fps = 15;
+ TMEDIA_PRODUCER(p_ddraw)->video.width = 352;
+ TMEDIA_PRODUCER(p_ddraw)->video.height = 288;
+
+ tsk_safeobj_init(p_ddraw);
+ }
+ return self;
}
/* destructor */
static tsk_object_t* _tdav_producer_screencast_ddraw_dtor(tsk_object_t * self)
{
- tdav_producer_screencast_ddraw_t *p_ddraw = (tdav_producer_screencast_ddraw_t *)self;
- if (p_ddraw) {
- /* stop */
- if (p_ddraw->b_started) {
- _tdav_producer_screencast_ddraw_stop((tmedia_producer_t*)p_ddraw);
- }
-
- /* deinit base */
- tmedia_producer_deinit(TMEDIA_PRODUCER(p_ddraw));
- /* deinit self */
+ tdav_producer_screencast_ddraw_t *p_ddraw = (tdav_producer_screencast_ddraw_t *)self;
+ if (p_ddraw) {
+ /* stop */
+ if (p_ddraw->b_started) {
+ _tdav_producer_screencast_ddraw_stop((tmedia_producer_t*)p_ddraw);
+ }
+
+ /* deinit base */
+ tmedia_producer_deinit(TMEDIA_PRODUCER(p_ddraw));
+ /* deinit self */
#if DDRAW_CPU_MONITOR || DDRAW_CPU_THROTTLING
- if (p_ddraw->p_timer_mgr) {
- tsk_timer_manager_destroy(&p_ddraw->p_timer_mgr);
- }
+ if (p_ddraw->p_timer_mgr) {
+ tsk_timer_manager_destroy(&p_ddraw->p_timer_mgr);
+ }
#endif /* DDRAW_CPU_MONITOR || DDRAW_CPU_THROTTLING */
#if DDRAW_MT
- for (int i = 0; i < sizeof(p_ddraw->mt.p_buff_yuv_aligned_array) / sizeof(p_ddraw->mt.p_buff_yuv_aligned_array[0]); ++i) {
- TSK_FREE_ALIGNED(p_ddraw->mt.p_buff_yuv_aligned_array[i]);
- }
- for (int i = 0; i < sizeof(p_ddraw->mt.h_events) / sizeof(p_ddraw->mt.h_events[0]); ++i) {
- if (p_ddraw->mt.h_events[i]) {
- CloseHandle(p_ddraw->mt.h_events[i]);
- p_ddraw->mt.h_events[i] = NULL;
- }
- }
+ for (int i = 0; i < sizeof(p_ddraw->mt.p_buff_yuv_aligned_array) / sizeof(p_ddraw->mt.p_buff_yuv_aligned_array[0]); ++i) {
+ TSK_FREE_ALIGNED(p_ddraw->mt.p_buff_yuv_aligned_array[i]);
+ }
+ for (int i = 0; i < sizeof(p_ddraw->mt.h_events) / sizeof(p_ddraw->mt.h_events[0]); ++i) {
+ if (p_ddraw->mt.h_events[i]) {
+ CloseHandle(p_ddraw->mt.h_events[i]);
+ p_ddraw->mt.h_events[i] = NULL;
+ }
+ }
#endif /* DDRAW_MT */
- TSK_FREE_ALIGNED(p_ddraw->p_buff_rgb_aligned);
- TSK_FREE_ALIGNED(p_ddraw->p_buff_yuv_aligned);
- DDRAW_SAFE_RELEASE(&p_ddraw->p_surf_primary);
- DDrawModuleSafeFree(p_ddraw->ddrawModule);
- tsk_safeobj_deinit(p_ddraw);
+ TSK_FREE_ALIGNED(p_ddraw->p_buff_rgb_aligned);
+ TSK_FREE_ALIGNED(p_ddraw->p_buff_yuv_aligned);
+ DDRAW_SAFE_RELEASE(&p_ddraw->p_surf_primary);
+ DDrawModuleSafeFree(p_ddraw->ddrawModule);
+ tsk_safeobj_deinit(p_ddraw);
- DDRAW_DEBUG_INFO("*** destroyed ***");
- }
+ DDRAW_DEBUG_INFO("*** destroyed ***");
+ }
- return self;
+ return self;
}
/* object definition */
-static const tsk_object_def_t tdav_producer_screencast_ddraw_def_s =
-{
- sizeof(tdav_producer_screencast_ddraw_t),
- _tdav_producer_screencast_ddraw_ctor,
- _tdav_producer_screencast_ddraw_dtor,
- tsk_null,
+static const tsk_object_def_t tdav_producer_screencast_ddraw_def_s = {
+ sizeof(tdav_producer_screencast_ddraw_t),
+ _tdav_producer_screencast_ddraw_ctor,
+ _tdav_producer_screencast_ddraw_dtor,
+ tsk_null,
};
/* plugin definition*/
-static const tmedia_producer_plugin_def_t tdav_producer_screencast_ddraw_plugin_def_s =
-{
- &tdav_producer_screencast_ddraw_def_s,
- tmedia_bfcp_video,
- "Microsoft DirectDraw screencast producer",
-
- _tdav_producer_screencast_ddraw_set,
- _tdav_producer_screencast_ddraw_prepare,
- _tdav_producer_screencast_ddraw_start,
- _tdav_producer_screencast_ddraw_pause,
- _tdav_producer_screencast_ddraw_stop
+static const tmedia_producer_plugin_def_t tdav_producer_screencast_ddraw_plugin_def_s = {
+ &tdav_producer_screencast_ddraw_def_s,
+ tmedia_bfcp_video,
+ "Microsoft DirectDraw screencast producer",
+
+ _tdav_producer_screencast_ddraw_set,
+ _tdav_producer_screencast_ddraw_prepare,
+ _tdav_producer_screencast_ddraw_start,
+ _tdav_producer_screencast_ddraw_pause,
+ _tdav_producer_screencast_ddraw_stop
};
const tmedia_producer_plugin_def_t *tdav_producer_screencast_ddraw_plugin_def_t = &tdav_producer_screencast_ddraw_plugin_def_s;
OpenPOWER on IntegriCloud