Skip to content

Instantly share code, notes, and snippets.

@qsniyg
Created March 18, 2020 13:51
Show Gist options
  • Select an option

  • Save qsniyg/82da0b0541162cfeb0313d0aa5703a97 to your computer and use it in GitHub Desktop.

Select an option

Save qsniyg/82da0b0541162cfeb0313d0aa5703a97 to your computer and use it in GitHub Desktop.
Null video codec driver
diff --git a/configure.ac b/configure.ac
index 7096e2fb66..90adbb9f92 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3549,6 +3549,7 @@ WINE_CONFIG_MAKEFILE(dlls/ntoskrnl.exe)
WINE_CONFIG_MAKEFILE(dlls/ntoskrnl.exe/tests)
WINE_CONFIG_MAKEFILE(dlls/ntprint)
WINE_CONFIG_MAKEFILE(dlls/ntprint/tests)
+WINE_CONFIG_MAKEFILE(dlls/nullvidc)
WINE_CONFIG_MAKEFILE(dlls/objsel)
WINE_CONFIG_MAKEFILE(dlls/odbc32)
WINE_CONFIG_MAKEFILE(dlls/odbcbcp)
diff --git a/dlls/nullvidc/Makefile.in b/dlls/nullvidc/Makefile.in
new file mode 100644
index 0000000000..1dbe7333b5
--- /dev/null
+++ b/dlls/nullvidc/Makefile.in
@@ -0,0 +1,9 @@
+MODULE = nullvidc.dll
+IMPORTS = user32
+
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+ nullvidc.c
+
+RC_SRCS = nullvidc.rc
diff --git a/dlls/nullvidc/nullvidc.c b/dlls/nullvidc/nullvidc.c
new file mode 100644
index 0000000000..f795bf5149
--- /dev/null
+++ b/dlls/nullvidc/nullvidc.c
@@ -0,0 +1,305 @@
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "commdlg.h"
+#include "vfw.h"
+#include "mmsystem.h"
+#include "nullvidc_private.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(nullvidc);
+
+static HINSTANCE NULL_hModule;
+
+#define NULL_MAGIC mmioFOURCC('n', 'u', 'l', 'l')
+#define compare_fourcc(fcc1, fcc2) (((fcc1)^(fcc2))&~0x20202020)
+
+typedef struct _NULL_Info {
+ DWORD dwMagic;
+ int depth;
+} NULL_Info;
+
+typedef BYTE uint8_t;
+
+
+static inline int get_stride(int width, int depth)
+{
+ return ((depth * width + 31) >> 3) & ~3;
+}
+
+
+static LRESULT NULL_DecompressQuery( NULL_Info *info, LPBITMAPINFO in, LPBITMAPINFO out )
+{
+ TRACE("ICM_DECOMPRESS_QUERY %p %p %p\n", info, in, out);
+
+ if( (info==NULL) || (info->dwMagic!=NULL_MAGIC) )
+ return ICERR_BADPARAM;
+
+ return ICERR_OK;
+}
+
+
+static LRESULT NULL_DecompressGetFormat( NULL_Info *info, LPBITMAPINFO in, LPBITMAPINFO out )
+{
+ DWORD size;
+
+ TRACE("ICM_DECOMPRESS_GETFORMAT %p %p %p\n", info, in, out);
+
+ if( (info==NULL) || (info->dwMagic!=NULL_MAGIC) )
+ return ICERR_BADPARAM;
+
+ size = in->bmiHeader.biSize;
+ if (in->bmiHeader.biBitCount <= 8)
+ size += in->bmiHeader.biClrUsed * sizeof(RGBQUAD);
+
+ if( out )
+ {
+ memcpy( out, in, size );
+ out->bmiHeader.biBitCount = 24;
+ out->bmiHeader.biCompression = BI_RGB;
+ out->bmiHeader.biSizeImage = get_stride(in->bmiHeader.biWidth, 24) * in->bmiHeader.biHeight;
+ return ICERR_OK;
+ }
+ return size;
+}
+
+
+static LRESULT NULL_DecompressBegin( NULL_Info *info, LPBITMAPINFO in, LPBITMAPINFO out )
+{
+ TRACE("ICM_DECOMPRESS_BEGIN %p %p %p\n", info, in, out);
+
+ if( (info==NULL) || (info->dwMagic!=NULL_MAGIC) )
+ return ICERR_BADPARAM;
+
+ TRACE("bitmap is %d bpp\n", in->bmiHeader.biBitCount);
+ if( in->bmiHeader.biBitCount == 8 )
+ info->depth = 8;
+ else if( in->bmiHeader.biBitCount == 16 )
+ info->depth = 16;
+ else if( in->bmiHeader.biBitCount == 24 )
+ info->depth = 24;
+ else if( in->bmiHeader.biBitCount == 32 )
+ info->depth = 32;
+ else
+ {
+ info->depth = 0;
+ FIXME("Unsupported output format %i\n", in->bmiHeader.biBitCount);
+ }
+
+ return ICERR_OK;
+}
+
+
+static void draw(void* output, int depth, LONG width, LONG height, LONG sz)
+{
+ LONG write_size;
+ BYTE *pixel_ptr, *pixel_end;
+
+ write_size = width * height * (depth / 8);
+ if (write_size > sz)
+ write_size = sz;
+
+ pixel_end = output + write_size;
+
+ for (pixel_ptr = output; pixel_ptr != pixel_end; pixel_ptr++) {
+ *pixel_ptr = 0;
+ }
+}
+
+
+static LRESULT NULL_Decompress( NULL_Info *info, ICDECOMPRESS *icd, DWORD size )
+{
+ LONG width, height, stride, sz, write_size;
+ void *output, *pixel_ptr, *pixel_end;
+
+ TRACE("ICM_DECOMPRESS %p %p %d\n", info, icd, size);
+
+ if( (info==NULL) || (info->dwMagic!=NULL_MAGIC) )
+ return ICERR_BADPARAM;
+
+ /* FIXME: flags are ignored */
+
+ width = icd->lpbiInput->biWidth;
+ height = icd->lpbiInput->biHeight;
+ sz = icd->lpbiInput->biSizeImage;
+
+ output = icd->lpOutput;
+
+ draw(output, info->depth, width, height, sz);
+
+ return ICERR_OK;
+}
+
+
+static LRESULT NULL_DecompressEx( NULL_Info *info, ICDECOMPRESSEX *icd, DWORD size )
+{
+ LONG width, height, stride, sz;
+ void *output;
+
+ TRACE("ICM_DECOMPRESSEX %p %p %d\n", info, icd, size);
+
+ if( (info==NULL) || (info->dwMagic!=NULL_MAGIC) )
+ return ICERR_BADPARAM;
+
+ /* FIXME: flags are ignored */
+
+ width = icd->lpbiSrc->biWidth;
+ height = icd->lpbiSrc->biHeight;
+ sz = icd->lpbiSrc->biSizeImage;
+
+ output = icd->lpDst;
+
+ draw(output, info->depth, width, height, sz);
+ return ICERR_OK;
+}
+
+
+static LRESULT NULL_GetInfo( NULL_Info *info, ICINFO *icinfo, DWORD dwSize )
+{
+ if (!icinfo) return sizeof(ICINFO);
+ if (dwSize < sizeof(ICINFO)) return 0;
+
+ icinfo->dwSize = sizeof(ICINFO);
+ icinfo->fccType = ICTYPE_VIDEO;
+ icinfo->fccHandler = info ? info->dwMagic : NULL_MAGIC;
+ icinfo->dwFlags = 0;
+ icinfo->dwVersion = ICVERSION;
+ icinfo->dwVersionICM = ICVERSION;
+
+ LoadStringW(NULL_hModule, IDS_NAME, icinfo->szName, ARRAY_SIZE(icinfo->szName));
+ LoadStringW(NULL_hModule, IDS_DESCRIPTION, icinfo->szDescription, ARRAY_SIZE(icinfo->szDescription));
+ /* msvfw32 will fill icinfo->szDriver for us */
+
+ return sizeof(ICINFO);
+}
+
+
+/***********************************************************************
+ * DriverProc
+ */
+LRESULT WINAPI NULL_DriverProc( DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg,
+ LPARAM lParam1, LPARAM lParam2 )
+{
+ NULL_Info *info = (NULL_Info *) dwDriverId;
+ LRESULT r = ICERR_UNSUPPORTED;
+
+ TRACE("%ld %p %04x %08lx %08lx\n", dwDriverId, hdrvr, msg, lParam1, lParam2);
+
+ switch( msg )
+ {
+ case DRV_LOAD:
+ TRACE("Loaded\n");
+ r = 1;
+ break;
+
+ case DRV_ENABLE:
+ break;
+
+ case DRV_OPEN:
+ {
+ ICINFO *icinfo = (ICINFO *)lParam2;
+
+ TRACE("Opened\n");
+
+ if (icinfo && compare_fourcc(icinfo->fccType, ICTYPE_VIDEO)) return 0;
+
+ info = HeapAlloc( GetProcessHeap(), 0, sizeof (NULL_Info) );
+ if( info )
+ {
+ memset( info, 0, sizeof *info );
+ info->dwMagic = NULL_MAGIC;
+ }
+ r = (LRESULT) info;
+ break;
+ }
+
+ case DRV_CLOSE:
+ TRACE("Closed\n");
+ HeapFree( GetProcessHeap(), 0, info );
+ break;
+
+ case DRV_DISABLE:
+ break;
+
+ case DRV_FREE:
+ break;
+
+ case ICM_GETINFO:
+ r = NULL_GetInfo( info, (ICINFO *)lParam1, (DWORD)lParam2 );
+ break;
+
+ case ICM_DECOMPRESS_QUERY:
+ r = NULL_DecompressQuery( info, (LPBITMAPINFO) lParam1,
+ (LPBITMAPINFO) lParam2 );
+ break;
+
+ case ICM_DECOMPRESS_GET_FORMAT:
+ r = NULL_DecompressGetFormat( info, (LPBITMAPINFO) lParam1,
+ (LPBITMAPINFO) lParam2 );
+ break;
+
+ case ICM_DECOMPRESS_GET_PALETTE:
+ FIXME("ICM_DECOMPRESS_GET_PALETTE\n");
+ break;
+
+ case ICM_DECOMPRESSEX_QUERY:
+ FIXME("ICM_DECOMPRESSEX_QUERY\n");
+ break;
+
+ case ICM_DECOMPRESS:
+ r = NULL_Decompress( info, (ICDECOMPRESS*) lParam1,
+ (DWORD) lParam2 );
+ break;
+
+ case ICM_DECOMPRESS_BEGIN:
+ r = NULL_DecompressBegin( info, (LPBITMAPINFO) lParam1,
+ (LPBITMAPINFO) lParam2 );
+ break;
+
+ case ICM_DECOMPRESSEX:
+ r = NULL_DecompressEx( info, (ICDECOMPRESSEX*) lParam1,
+ (DWORD) lParam2 );
+ break;
+
+ case ICM_DECOMPRESS_END:
+ r = ICERR_OK;
+ break;
+
+ case ICM_COMPRESS_QUERY:
+ r = ICERR_BADFORMAT;
+ /* fall through */
+ case ICM_COMPRESS_GET_FORMAT:
+ case ICM_COMPRESS_END:
+ case ICM_COMPRESS:
+ FIXME("compression not implemented\n");
+ break;
+
+ case ICM_CONFIGURE:
+ break;
+
+ default:
+ FIXME("Unknown message: %04x %ld %ld\n", msg, lParam1, lParam2);
+ }
+
+ return r;
+}
+
+/***********************************************************************
+ * DllMain
+ */
+BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
+{
+ TRACE("(%p,%d,%p)\n", hModule, dwReason, lpReserved);
+
+ switch (dwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hModule);
+ NULL_hModule = hModule;
+ break;
+ }
+ return TRUE;
+}
diff --git a/dlls/nullvidc/nullvidc.rc b/dlls/nullvidc/nullvidc.rc
new file mode 100644
index 0000000000..399cb14e59
--- /dev/null
+++ b/dlls/nullvidc/nullvidc.rc
@@ -0,0 +1,11 @@
+#include "nullvidc_private.h"
+
+#pragma makedep po
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+{
+ IDS_NAME "#msgctxt#do not translate#MS-NULL"
+ IDS_DESCRIPTION "Wine null video codec"
+}
diff --git a/dlls/nullvidc/nullvidc.spec b/dlls/nullvidc/nullvidc.spec
new file mode 100644
index 0000000000..aec2706b8e
--- /dev/null
+++ b/dlls/nullvidc/nullvidc.spec
@@ -0,0 +1 @@
+@ stdcall -private DriverProc(long long long long long) NULL_DriverProc
diff --git a/dlls/nullvidc/nullvidc_private.h b/dlls/nullvidc/nullvidc_private.h
new file mode 100644
index 0000000000..f087460e56
--- /dev/null
+++ b/dlls/nullvidc/nullvidc_private.h
@@ -0,0 +1,9 @@
+#ifndef __NULLVIDC_PRIVATE_H
+#define __NULLVIDC_PRIVATE_H
+
+#include <windef.h>
+
+#define IDS_NAME 100
+#define IDS_DESCRIPTION 101
+
+#endif /* __NULLVIDC_PRIVATE_H */
--
2.25.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment