Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • wine/wine
  • rbernon/wine
  • stefan/wine
  • FireBurn/wine
  • alesliehughes/wine
  • zhiyi/wine
  • huw/wine
  • jsikorski/wine
  • hmc/wine
  • dadangnh/wine
  • epo/wine
  • dlesho/wine
  • DarkShadow44/wine
  • iamahuman/wine
  • jacek/wine
  • mstorsjo/wine
  • gofman/wine
  • alexhenrie/wine
  • giomasce/wine
  • tclem/wine
  • besentv/wine
  • dlehman25/wine
  • aeikum/wine
  • cdavis5e/wine
  • sbaars/wine
  • baskanov/wine
  • pperdigao/wine
  • DavidHusicka/wine
  • DadSchoorse/wine
  • gverm/wine
  • bshanks/wine
  • gonzoMD/wine
  • Mystral/wine
  • tmatthies/wine
  • zlice/wine
  • AndreRH/wine
  • madewokherd/wine
  • zfigura/wine
  • fgouget/wine
  • nsivov/wine
  • ElementalWarrior/wine
  • piotr/wine
  • timozuccarello/wine
  • DavidCurtiss/wine
  • cmcadams/wine
  • davidebeatrici/wine
  • hans/wine
  • insn/wine
  • danrm/wine
  • jklemann/wine
  • saedo/wine
  • sgwaki/wine
  • puetzk/wine
  • bernhardu/wine
  • ReDress/wine
  • jlucfarias/wine
  • sloper42/wine
  • ivyl/wine
  • zhui/wine
  • julliard/wine
  • ClearlyClaire/wine
  • Alexander-Wilms/wine
  • rndtrash/wine
  • redmcg/wine
  • jkfloris/wine
  • maljaf/wine
  • Tuupertunut/wine
  • bsjeon/wine
  • tati/wine
  • whydoubt/wine
  • doitsujin/wine
  • shaunren/wine
  • szanni/wine
  • tobi.goergens/wine-cabinet-patch
  • winspool/wine
  • olivierfrdierick/wine
  • linkmauve/wine
  • jin-king1/wine
  • yeyeshun/wine
  • sulix/wine
  • bgc/wine
  • fanwenjie/wine
  • IncubusRK/wine
  • js6pak/wine
  • AurimasF/wine
  • etaash.mathamsetty/wine
  • hverbeet/wine
  • Fox2Code/wine
  • jhol/wine
  • jrueger/wine
  • afrantzis/wine
  • lauri.kentta/wine
  • ehoover/wine
  • cdenton/wine
  • jkloetzke/wine
  • baryluk/wine
  • restet/wine-personal
  • orudge/wine
  • Gcenx/wine
  • mstefani/wine
  • hibbsncc1701/wine
  • jchw/wine
  • moceap/wine
  • Skryptonyte/wine
  • marzent/wine
  • msmeissn/wine
  • learn-more/wine
  • logos128/wine
  • xe/wine
  • florian-kuebler/wine
  • eason329/wine
  • gang65/wine
  • binarymaster/wine
  • nbosio1001/wine
  • sh.owais95/wine
  • yaoyuan.0553/wine
  • AnthonyLaurienti/wine
  • mivanchev/wine
  • Hi-Angel/wine
  • vt/wine
  • wyrquill/wine
  • waynus/wine
  • wuliande/wine
  • yao.yuan.wn/wine
  • K1K1/wine
  • lukehutch1027/wine
  • etang-cw/wine
  • Josueblanco/wine
  • jplotz/wine
  • j20001970/wine
  • jsm174/wine
  • aricstewart/wine
  • uncoveryoureyestheresnosun/wine
  • VitorRamos/wine
  • 0e4ef622/wine
  • tj4048750/wine
  • xantares/wine
  • maxfigura/wine
  • sanane/wine
  • juniorjr9345/wine
  • lucaspereira1234/wine
  • gerald/wine
  • lepemiguel32/wine
  • caibb2018/wine
  • CNB_Kevin/wine
  • thc13/wine
  • jaihysc/wine
  • youngsecurity/wine
  • chendeqiang1024/wine
  • rhendric/wine
  • databoose/wine
  • memory-thrasher/wine
  • salman.tajik22/wine
  • CowFroggers/wine
  • kbdharun/wine
  • dreamer/wine
  • babyjoey711/wine
  • ripxorip/wine
  • PSzczepanski1996/wine
  • steveshe006/wine
  • joshua/wine
  • cmccarthy/wine
  • tomjansen/wine
  • sonyps5201314/wine
  • katelynnking4281/wine
  • dhary686/wine
  • mathematician/wine
  • rhabacker/wine
  • steveschnepp/wine
  • nekotekina/wine
  • Aaron1011/wine
  • catsout/wine
  • kasper93/wine
  • beef331/wine
  • ESD/wine
  • sarosib/wine
  • ghurmcardash/wine
  • AMZN-hgoffin/wine
  • gtmikw/wine
  • Keming/wine
  • dpjh747-gl/wine
  • tzluo/wine
  • rfz/wine
  • illia.a.polishchuk/wine
  • new_kleth/wine
  • serkan-maker/wine
  • w-flo/wine
  • mikayahlevi/wine
  • nulleve/wine
  • pgruebele/wine
  • athiele/wine
  • paparaha4/wine
  • novenary/wine
  • Plavil/wine
  • longjunyu/wine
  • chrisli/wine
  • samkottler/wine
  • danielzgtg/wine
  • twcassel/wine
  • guo/wine
  • didier31/wine
  • Zhaoyi/wine
  • twhitehead/wine
  • svyatpro/wine
  • infyquest/wine-iq-devel
  • sebres/wine
  • endrift/wine
  • zhengbl/wine
  • joelikeyan/wine
  • IsaacMarovitz/wine
  • LouiseTheGoldenGoddess/wine
  • SergeGautherie/wine
  • Klittiklatsch/wine
  • ldhacker/wine
  • dk1006498/wine
  • ishitatsuyuki/wine
  • h3c/wine
  • wincenty.bandyta41/wine
  • ayhankus482/wine
  • q4a/wine
  • mjgarton/wine
  • agusev/wine
  • vovams/wine
  • shardulsb08/wine
  • lylythechosenone/wine
  • artemist/wine
  • dropbear/wine
  • Cherser-s/wine
  • smayr/wine
  • loveptong/wine
  • chendeqiang/wine
  • gaber139/wine
  • shytzedaka/wine
  • ghkmufc/wine
  • TornadoCookie/wine
  • klownwolfman/wine
  • bylaws/wine
  • vitorhnn/wine
  • mide1337/wine
  • mewinkler/wine
  • firelzrd/wine
  • Samsuper/wine
  • kkartaltepe/wine
  • petravion/wine
  • Maaka00524/jacob-wine
  • petrathekat/wine
  • dj/wine
  • liam-middlebrook/wine
  • padolkarlucky/wine
  • maarten/wine
  • yhd986/wine
  • linkmecry/wine
  • tehrantoday/wine
  • xuxin12345/wine
  • dmjc/wine
  • sedwards/wine
  • hanslehnert/wine
  • 3ts75/wine
  • EkaterinePapava/wine
  • lav/wine
  • lygstate/wine
  • mxkrsv/wine
  • xutaxkamay/wine
  • cbialorucki/wine
  • yshui/wine
  • baikaishiuc/wine
  • HuwCampbell/wine
  • llde/wine
  • rockdrilla/wine
  • aidanhs/wine
  • SwimmingTiger/wine
  • fvalasiad/wine
  • zsoltiv/wine
  • mailnew4ster/wine
  • ake.rehnman/wine
  • IDocin/wine
  • dmitry/wine
  • Cthuflu/wine
  • corngood/wine
  • whindsaks/wine
  • telans/wine
  • DmitrySokolov/wine
  • Pospelove/wine
  • ellingtonsantos/wine
  • roro/wine
  • wurenny/wine
  • KokoseiJ/wine
  • amurzeau/wine
  • spazzymoto/wine
  • searchingin/wine
  • marler8997/wine
  • Alcaro/wine
  • aunali1/wine
  • snaccslocc420/wine
  • ajkhoury/wine
  • qsniyg/wine
  • Matheus-TestUser1/wine
  • adamrehn/wine
  • brobston/wine
  • aalyaev/wine
  • thongthai/wine
  • j.bayer1988/wine
  • skitt/wine
  • benben/wine
  • ahmouse15/wine
  • achurch/wine
  • mfaqiri2/wine
  • yseo/wine
  • kingjinni/wine
  • userid0x0/wine
  • titan/wine
  • Komoszek/wine
  • GamzeeRakoon/wine
  • joanluc/wine
  • Alan/wine
  • meshine/wine
  • EBADF/wine
  • vibhavp/wine
  • quininer/wine
  • pawelulita/wine
  • muek2211/wine
  • chenhaoyang/wine
  • nishiyama/wine
  • silviuxgaming/wine
  • nell/wine
  • 29jm/wine
  • arilou/wine
  • Mini-Gaunt/wine
  • DodoGTA/wine
  • davispuh/wine
  • mzent/wine
  • arakmar/wine
  • number201724/wine
  • yhd986/wine-up
  • rpisl/wine
  • zp1/wine-zp-cs-464
  • h0tc0d3/wine
  • Snowiiii/wine
  • gabrielb/wine
  • PureBulb/wine
  • OO/wine
  • Clara/wine
  • Saancreed/wine
  • enolp/wine
  • arthunix/wine
  • halfline/wine
  • carlo-bramini/wine
  • jfmu/wine
  • russelltg/wine
  • ntay/wine
  • YellowOnion/wine
  • niversesu/wine
  • gilvbp/wine
  • tingling0072/wine
  • DandD1517/wine
  • rastos/add-GetAnycastIpAddressTable
  • gnif/wine
  • gibsonpil/wine
  • antenabr2/wine
  • kvashis/wine
  • CKolle/wine
  • kubni/wine
  • ten0s/wine
  • Yvonne8873/wine
  • kurikaesu/wine
  • minggr/wine
  • JohnSebastienNadeau/wine
  • karshnicholas/wine
  • SamB/wine
  • apgrc/wine
  • Samiklom/wine
  • llyyr/wine
  • nberner/wine
  • katharinechui/wine
  • kirill.zhumarin/wine
  • vaxerski/wine
  • infiniteloop/wine
  • K0bin/wine
  • arethusa/wine
  • mrdeathjr28/wine
  • dank_meme/wine
  • dh/wine
  • tuomasjjrasanen/wine
  • mmcdonnell/wine
  • mxnny00/wine-manjaro-arch-compatibility
  • Joan/wine
  • g.mo.alcauter/wine
  • zhenbo_li/wine
  • tsmx/wine
  • xaqumin/wine
  • peterjc123/wine
  • ruslangaripov/wine
  • blyss/wine
  • xanathar/wine
  • michael.bond/wine
  • Quix0r/wine
  • sinisa.susnjar/wine
  • Rapid/wine
  • theli.ua/wine
  • shaun.din/wine
  • zhaohongxin/wine
  • dylan.eskew/wine
  • humbertoperezs991/wine
  • vaevi/wine
  • Riesi/wine
  • francisdb/wine
  • 1480c1/wine
  • trcrsired/wine
  • npatt/wine
  • muhammmadalli/wine9.0
  • Czahrien/wine
  • nilsen.jonas/wine
  • underdogest/wine
  • djordjem/wine
  • frubin/wine
  • LucasChollet/wine
  • lipengfei-loongson/wine
  • JacobCzekalla/wine-fork-jacob
  • omar_elantil/wine
  • lumarel/wine
  • principeagustin/wine
  • gotzl/wine
  • OneTester250376/wine
  • austin987/wine
  • unknown62627/wine
  • navi/wine
  • somedevfox/wine
  • notaz/wine
  • fcasas/wine
  • Asteroz/wine
  • MariusSchiffer/wine
  • kevinrmartinez/wine-devel
  • St1gven/wine
  • maarten256/wine
  • rcstarr87/wine
  • tinozzo123/wine
  • GermanAizek/wine
  • spencerwallace/wine
  • schloegl/wine
  • giuppococco/wine
  • shayan7878/wine
  • N080DY12/wine
  • ralf.habacker/wine
  • oh-ok/wine
  • johnporter/wine
  • Low-power/wine
  • thelande/wine
  • riyu12383/wine
  • kubapet/wine
  • Ivan_83/wine
  • SmithGoll/wine
  • gmesmer/wine
  • akarisu.de/wine
  • jwffrey9046/wine
  • anders/wine
  • markbhasawut/wine
  • dy-tea/wine
  • Benjamin_Loison/wine
  • frmdstryr/wine
  • zzam/wine
  • haydenhestad/wine
  • Deppy04/wine
  • osbre/wine
  • CharlottePabst/wine
  • SunlitTango/wine
  • ritalat/wine
  • AlexeyLushnikov/wine
  • mickdermack/wine
  • s1UMBa/wine
  • huangqinjin/wine
  • caseyr297/wine
  • d1saster/wine
  • ayufdh222/wine
  • janstrakowski/wine
  • petur/wine
  • matheus.venturini/wine-fix-ohm-sign
  • rayrapetyan/wine
  • xiaotong/wine
  • ovarley1/wine
  • dos1/wine
  • BZZZZ/wine
  • joesoroka/wine
  • toadking/wine
  • JoshuaBrest/wine
  • elias/wine
  • michele.dionisio/wine
  • garlett/wine-send-arp
  • eugenemcardle/wine
  • hugwijst/wine
  • whrvt/wine
  • loisgomez/wine
  • ramleejo/wine
  • self/wine
  • fr33z00/wine
  • JoeS209/wine
  • JacKeTUs/wine
  • nak.ak2015/wine
  • morgwai/wine
  • funfunctor/wine
  • donnyjoe/wine
  • sitter/wine
  • atticf/wine
  • xipster/wine
  • sebastian/wine
  • AlexanderWillner/wine
  • yaoyongjie/wine
  • wayne/wine
  • AMark/wine
  • zamaudio/wine
  • TomaszPakula/wine
  • Freakness109/wine
  • amorozov/wine
  • HP/wine
  • danlm/wine
  • rariema/wine
  • Biswa96/wine
  • rlippmann/wine
  • yangkun/wine
  • greyghoster/wine
519 results
Show changes
Commits on Source (34)
Showing
with 822 additions and 189 deletions
...@@ -153,6 +153,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_macho); ...@@ -153,6 +153,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_macho);
#define MACHO_CPU_TYPE_X86 0x00000007 #define MACHO_CPU_TYPE_X86 0x00000007
#define MACHO_CPU_TYPE_X86_64 0x01000007 #define MACHO_CPU_TYPE_X86_64 0x01000007
#define MACHO_CPU_TYPE_ARM 0x0000000c
#define MACHO_CPU_TYPE_ARM64 0x0100000c
#define MACHO_MH_EXECUTE 0x2 #define MACHO_MH_EXECUTE 0x2
#define MACHO_MH_DYLIB 0x6 #define MACHO_MH_DYLIB 0x6
...@@ -212,6 +214,8 @@ static USHORT macho_cpu_to_machine(unsigned cpu) ...@@ -212,6 +214,8 @@ static USHORT macho_cpu_to_machine(unsigned cpu)
{ {
case MACHO_CPU_TYPE_X86: return IMAGE_FILE_MACHINE_I386; case MACHO_CPU_TYPE_X86: return IMAGE_FILE_MACHINE_I386;
case MACHO_CPU_TYPE_X86_64: return IMAGE_FILE_MACHINE_AMD64; case MACHO_CPU_TYPE_X86_64: return IMAGE_FILE_MACHINE_AMD64;
case MACHO_CPU_TYPE_ARM: return IMAGE_FILE_MACHINE_ARMNT;
case MACHO_CPU_TYPE_ARM64: return IMAGE_FILE_MACHINE_ARM64;
default: default:
FIXME("Untranslated Mach-O CPU %x\n", cpu); FIXME("Untranslated Mach-O CPU %x\n", cpu);
return IMAGE_FILE_MACHINE_UNKNOWN; return IMAGE_FILE_MACHINE_UNKNOWN;
......
...@@ -797,26 +797,21 @@ static LRESULT ICCVID_DecompressQuery( ICCVID_Info *info, LPBITMAPINFO in, LPBIT ...@@ -797,26 +797,21 @@ static LRESULT ICCVID_DecompressQuery( ICCVID_Info *info, LPBITMAPINFO in, LPBIT
if( in->bmiHeader.biWidth != out->bmiHeader.biWidth ) if( in->bmiHeader.biWidth != out->bmiHeader.biWidth )
return ICERR_BADFORMAT; return ICERR_BADFORMAT;
switch( out->bmiHeader.biBitCount ) switch( out->bmiHeader.biCompression )
{ {
case 16: case BI_RGB:
if ( out->bmiHeader.biCompression == BI_BITFIELDS ) if ( out->bmiHeader.biBitCount == 16 || out->bmiHeader.biBitCount == 24 || out->bmiHeader.biBitCount == 32 )
{ return ICERR_OK;
if ( !ICCVID_CheckMask(out->bmiColors, 0x7C00, 0x03E0, 0x001F) &&
!ICCVID_CheckMask(out->bmiColors, 0xF800, 0x07E0, 0x001F) )
{
TRACE("unsupported output bit field(s) for 16-bit colors\n");
return ICERR_BADFORMAT;
}
}
break; break;
case 24: case BI_BITFIELDS:
case 32: if ( out->bmiHeader.biBitCount == 16 && ICCVID_CheckMask(out->bmiColors, 0x7C00, 0x03E0, 0x001F) )
return ICERR_OK;
if ( out->bmiHeader.biBitCount == 16 && ICCVID_CheckMask(out->bmiColors, 0xF800, 0x07E0, 0x001F) )
return ICERR_OK;
break; break;
default:
TRACE("unsupported output bitcount = %d\n", out->bmiHeader.biBitCount );
return ICERR_BADFORMAT;
} }
TRACE("unsupported output format\n");
return ICERR_BADFORMAT;
} }
return ICERR_OK; return ICERR_OK;
......
...@@ -604,7 +604,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteProcessMemory( HANDLE process, void *addr, co ...@@ -604,7 +604,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteProcessMemory( HANDLE process, void *addr, co
SIZE_T size, SIZE_T *bytes_written ) SIZE_T size, SIZE_T *bytes_written )
{ {
CROSS_PROCESS_WORK_LIST *list = open_cross_process_connection( process ); CROSS_PROCESS_WORK_LIST *list = open_cross_process_connection( process );
DWORD old_prot, prot = PAGE_TARGETS_NO_UPDATE | PAGE_ENCLAVE_NO_CHANGE | PAGE_EXECUTE_WRITECOPY; DWORD old_prot, prot = PAGE_TARGETS_NO_UPDATE | PAGE_ENCLAVE_NO_CHANGE;
MEMORY_BASIC_INFORMATION info; MEMORY_BASIC_INFORMATION info;
void *base_addr; void *base_addr;
SIZE_T region_size; SIZE_T region_size;
...@@ -634,6 +634,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteProcessMemory( HANDLE process, void *addr, co ...@@ -634,6 +634,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteProcessMemory( HANDLE process, void *addr, co
base_addr = ROUND_ADDR( addr ); base_addr = ROUND_ADDR( addr );
region_size = ROUND_SIZE( addr, size ); region_size = ROUND_SIZE( addr, size );
region_size = min( region_size, (char *)info.BaseAddress + info.RegionSize - (char *)base_addr ); region_size = min( region_size, (char *)info.BaseAddress + info.RegionSize - (char *)base_addr );
prot |= (info.Type == MEM_PRIVATE) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_WRITECOPY;
send_cross_process_notification( list, CrossProcessPreVirtualProtect, send_cross_process_notification( list, CrossProcessPreVirtualProtect,
base_addr, region_size, 1, prot ); base_addr, region_size, 1, prot );
......
...@@ -1274,6 +1274,7 @@ static void session_close(struct media_session *session) ...@@ -1274,6 +1274,7 @@ static void session_close(struct media_session *session)
switch (session->state) switch (session->state)
{ {
case SESSION_STATE_STOPPED: case SESSION_STATE_STOPPED:
case SESSION_STATE_RESTARTING_SOURCES:
hr = session_finalize_sinks(session); hr = session_finalize_sinks(session);
break; break;
case SESSION_STATE_STARTED: case SESSION_STATE_STARTED:
...@@ -3192,8 +3193,15 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre ...@@ -3192,8 +3193,15 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre
break; break;
} }
if (session->presentation.flags & SESSION_FLAG_END_OF_PRESENTATION || FAILED(hr)) if (session->presentation.flags & SESSION_FLAG_END_OF_PRESENTATION)
session_set_stopped(session, hr); session_set_stopped(session, hr);
else if (FAILED(hr))
{
if (session->presentation.flags & SESSION_FLAG_FINALIZE_SINKS)
session_set_closed(session, hr);
else
session_set_stopped(session, hr);
}
break; break;
default: default:
......
...@@ -6249,6 +6249,8 @@ static void test_media_session_Start(void) ...@@ -6249,6 +6249,8 @@ static void test_media_session_Start(void)
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaSession_Close(session); hr = IMFMediaSession_Close(session);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = wait_media_event(session, callback, MESessionClosed, 1000, &propvar);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
/* Media session is shut down */ /* Media session is shut down */
hr = IMFMediaSource_Shutdown(source); hr = IMFMediaSource_Shutdown(source);
...@@ -6331,6 +6333,8 @@ static void test_media_session_Start(void) ...@@ -6331,6 +6333,8 @@ static void test_media_session_Start(void)
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaSession_Close(session); hr = IMFMediaSession_Close(session);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = wait_media_event(session, callback, MESessionClosed, 1000, &propvar);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaSession_Shutdown(session); hr = IMFMediaSession_Shutdown(session);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaSource_Shutdown(source); hr = IMFMediaSource_Shutdown(source);
...@@ -6534,6 +6538,88 @@ static void test_MFEnumDeviceSources(void) ...@@ -6534,6 +6538,88 @@ static void test_MFEnumDeviceSources(void)
CoUninitialize(); CoUninitialize();
} }
static void test_media_session_Close(void)
{
media_type_desc video_rgb32_desc =
{
ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32),
};
struct test_grabber_callback *grabber_callback;
IMFPresentationClock *presentation_clock;
IMFActivate *sink_activate;
IMFAsyncCallback *callback;
IMFMediaType *output_type;
IMFMediaSession *session;
IMFMediaSource *source;
IMFTopology *topology;
PROPVARIANT propvar;
IMFClock *clock;
UINT64 duration;
HRESULT hr;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
if (!(source = create_media_source(L"test.mp4", L"video/mp4")))
{
todo_wine /* Gitlab CI Debian runner */
win_skip("MP4 media source is not supported, skipping tests.\n");
MFShutdown();
return;
}
grabber_callback = impl_from_IMFSampleGrabberSinkCallback(create_test_grabber_callback());
hr = MFCreateMediaType(&output_type);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
init_media_type(output_type, video_rgb32_desc, -1);
hr = MFCreateSampleGrabberSinkActivate(output_type, &grabber_callback->IMFSampleGrabberSinkCallback_iface, &sink_activate);
ok(hr == S_OK, "Failed to create grabber sink, hr %#lx.\n", hr);
IMFMediaType_Release(output_type);
hr = MFCreateMediaSession(NULL, &session);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
topology = create_test_topology(source, sink_activate, &duration);
hr = IMFMediaSession_SetTopology(session, 0, topology);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
IMFTopology_Release(topology);
hr = IMFMediaSession_GetClock(session, &clock);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFClock_QueryInterface(clock, &IID_IMFPresentationClock, (void **)&presentation_clock);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
IMFClock_Release(clock);
propvar.vt = VT_EMPTY;
hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
callback = create_test_callback(TRUE);
hr = wait_media_event(session, callback, MESessionStarted, 5000, &propvar);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaSession_Close(session);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaSource_Shutdown(source);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = wait_media_event_until_blocking(session, callback, MESessionClosed, 5000, &propvar);
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaSession_Shutdown(session);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
IMFPresentationClock_Release(presentation_clock);
IMFAsyncCallback_Release(callback);
IMFMediaSession_Release(session);
IMFActivate_ShutdownObject(sink_activate);
IMFActivate_Release(sink_activate);
IMFSampleGrabberSinkCallback_Release(&grabber_callback->IMFSampleGrabberSinkCallback_iface);
IMFMediaSource_Release(source);
hr = MFShutdown();
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
}
START_TEST(mf) START_TEST(mf)
{ {
init_functions(); init_functions();
...@@ -6568,4 +6654,5 @@ START_TEST(mf) ...@@ -6568,4 +6654,5 @@ START_TEST(mf)
test_MFCreateSequencerSegmentOffset(); test_MFCreateSequencerSegmentOffset();
test_media_session_Start(); test_media_session_Start();
test_MFEnumDeviceSources(); test_MFEnumDeviceSources();
test_media_session_Close();
} }
...@@ -3585,6 +3585,8 @@ static void test_wma_decoder_dmo_output_type(void) ...@@ -3585,6 +3585,8 @@ static void test_wma_decoder_dmo_output_type(void)
good_output_type = (void *)buffer_good_output; good_output_type = (void *)buffer_good_output;
bad_output_type = (void *)buffer_bad_output; bad_output_type = (void *)buffer_bad_output;
init_dmo_media_type_audio(input_type, input_subtype, channel_count, rate, 16); init_dmo_media_type_audio(input_type, input_subtype, channel_count, rate, 16);
((WAVEFORMATEX *)(input_type + 1))->nBlockAlign = 640;
((WAVEFORMATEX *)(input_type + 1))->nAvgBytesPerSec = 2000;
init_dmo_media_type_audio(good_output_type, &MEDIASUBTYPE_PCM, channel_count, rate, bits_per_sample); init_dmo_media_type_audio(good_output_type, &MEDIASUBTYPE_PCM, channel_count, rate, bits_per_sample);
memset(bad_output_type, 0, sizeof(buffer_bad_output)); memset(bad_output_type, 0, sizeof(buffer_bad_output));
......
...@@ -117,7 +117,7 @@ static HRESULT get_periods(struct audio_client *client, ...@@ -117,7 +117,7 @@ static HRESULT get_periods(struct audio_client *client,
return params.result; return params.result;
} }
static HRESULT adjust_timing(struct audio_client *client, static HRESULT adjust_timing(struct audio_client *client, const BOOLEAN force_def_period,
REFERENCE_TIME *duration, REFERENCE_TIME *period, REFERENCE_TIME *duration, REFERENCE_TIME *period,
const AUDCLNT_SHAREMODE mode, const DWORD flags, const AUDCLNT_SHAREMODE mode, const DWORD flags,
const WAVEFORMATEX *fmt) const WAVEFORMATEX *fmt)
...@@ -133,28 +133,31 @@ static HRESULT adjust_timing(struct audio_client *client, ...@@ -133,28 +133,31 @@ static HRESULT adjust_timing(struct audio_client *client,
TRACE("Device periods: %lu default and %lu minimum\n", (ULONG)def_period, (ULONG)min_period); TRACE("Device periods: %lu default and %lu minimum\n", (ULONG)def_period, (ULONG)min_period);
if (mode == AUDCLNT_SHAREMODE_SHARED) { if (mode == AUDCLNT_SHAREMODE_SHARED) {
*period = def_period; if (*period == 0 || force_def_period)
*period = def_period;
else if (*period < min_period)
return AUDCLNT_E_INVALID_DEVICE_PERIOD;
if (*duration < 3 * *period) if (*duration < 3 * *period)
*duration = 3 * *period; *duration = 3 * *period;
} else { } else {
const WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE *)fmt; const WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE *)fmt;
if (fmtex->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE && if (fmtex->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
(fmtex->dwChannelMask == 0 || fmtex->dwChannelMask & SPEAKER_RESERVED)) (fmtex->dwChannelMask == 0 || fmtex->dwChannelMask & SPEAKER_RESERVED))
hr = AUDCLNT_E_UNSUPPORTED_FORMAT; return AUDCLNT_E_UNSUPPORTED_FORMAT;
else { else {
if (*period == 0) if (*period == 0)
*period = def_period; *period = def_period;
if (*period < min_period || *period > 5000000) if (*period < min_period || *period > 5000000)
hr = AUDCLNT_E_INVALID_DEVICE_PERIOD; return AUDCLNT_E_INVALID_DEVICE_PERIOD;
else if (*duration > 20000000) /* The smaller the period, the lower this limit. */ else if (*duration > 20000000) /* The smaller the period, the lower this limit. */
hr = AUDCLNT_E_BUFFER_SIZE_ERROR; return AUDCLNT_E_BUFFER_SIZE_ERROR;
else if (flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) { else if (flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) {
if (*duration != *period) if (*duration != *period)
hr = AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL; return AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL;
FIXME("EXCLUSIVE mode with EVENTCALLBACK\n"); FIXME("EXCLUSIVE mode with EVENTCALLBACK\n");
hr = AUDCLNT_E_DEVICE_IN_USE; return AUDCLNT_E_DEVICE_IN_USE;
} else if (*duration < 8 * *period) } else if (*duration < 8 * *period)
*duration = 8 * *period; /* May grow above 2s. */ *duration = 8 * *period; /* May grow above 2s. */
} }
...@@ -355,6 +358,100 @@ skip: ...@@ -355,6 +358,100 @@ skip:
return wcsdup(name); return wcsdup(name);
} }
static HRESULT stream_init(struct audio_client *client, const BOOLEAN force_def_period,
const AUDCLNT_SHAREMODE mode, const DWORD flags,
REFERENCE_TIME duration, REFERENCE_TIME period,
const WAVEFORMATEX *fmt, const GUID *sessionguid)
{
struct create_stream_params params;
UINT32 i, channel_count;
stream_handle stream;
WCHAR *name;
if (!fmt)
return E_POINTER;
dump_fmt(fmt);
if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE)
return E_INVALIDARG;
if (flags & ~(AUDCLNT_STREAMFLAGS_CROSSPROCESS |
AUDCLNT_STREAMFLAGS_LOOPBACK |
AUDCLNT_STREAMFLAGS_EVENTCALLBACK |
AUDCLNT_STREAMFLAGS_NOPERSIST |
AUDCLNT_STREAMFLAGS_RATEADJUST |
AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED |
AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE |
AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED |
AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY |
AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM)) {
FIXME("Unknown flags: %08lx\n", flags);
return E_INVALIDARG;
}
if (FAILED(params.result = adjust_timing(client, force_def_period, &duration, &period, mode, flags, fmt)))
return params.result;
sessions_lock();
if (client->stream) {
sessions_unlock();
return AUDCLNT_E_ALREADY_INITIALIZED;
}
if (FAILED(params.result = main_loop_start())) {
sessions_unlock();
return params.result;
}
params.name = name = get_application_name();
params.device = client->device_name;
params.flow = client->dataflow;
params.share = mode;
params.flags = flags;
params.duration = duration;
params.period = period;
params.fmt = fmt;
params.channel_count = &channel_count;
params.stream = &stream;
wine_unix_call(create_stream, &params);
free(name);
if (FAILED(params.result)) {
sessions_unlock();
return params.result;
}
if (!(client->vols = malloc(channel_count * sizeof(*client->vols)))) {
params.result = E_OUTOFMEMORY;
goto exit;
}
for (i = 0; i < channel_count; i++)
client->vols[i] = 1.f;
params.result = get_audio_session(sessionguid, client->parent, channel_count, &client->session);
exit:
if (FAILED(params.result)) {
stream_release(stream, NULL);
free(client->vols);
client->vols = NULL;
} else {
list_add_tail(&client->session->clients, &client->entry);
client->stream = stream;
client->channel_count = channel_count;
set_stream_volumes(client);
}
sessions_unlock();
return params.result;
}
static HRESULT WINAPI capture_QueryInterface(IAudioCaptureClient *iface, REFIID riid, void **ppv) static HRESULT WINAPI capture_QueryInterface(IAudioCaptureClient *iface, REFIID riid, void **ppv)
{ {
struct audio_client *This = impl_from_IAudioCaptureClient(iface); struct audio_client *This = impl_from_IAudioCaptureClient(iface);
...@@ -537,97 +634,12 @@ static HRESULT WINAPI client_Initialize(IAudioClient3 *iface, AUDCLNT_SHAREMODE ...@@ -537,97 +634,12 @@ static HRESULT WINAPI client_Initialize(IAudioClient3 *iface, AUDCLNT_SHAREMODE
const WAVEFORMATEX *fmt, const GUID *sessionguid) const WAVEFORMATEX *fmt, const GUID *sessionguid)
{ {
struct audio_client *This = impl_from_IAudioClient3(iface); struct audio_client *This = impl_from_IAudioClient3(iface);
struct create_stream_params params;
UINT32 i, channel_count;
stream_handle stream;
WCHAR *name;
TRACE("(%p)->(%x, %lx, %s, %s, %p, %s)\n", This, mode, flags, wine_dbgstr_longlong(duration), TRACE("(%p)->(%x, %lx, %s, %s, %p, %s)\n", This, mode, flags, wine_dbgstr_longlong(duration),
wine_dbgstr_longlong(period), fmt, wine_dbgstr_longlong(period), fmt,
debugstr_guid(sessionguid)); debugstr_guid(sessionguid));
if (!fmt) return stream_init(This, TRUE, mode, flags, duration, period, fmt, sessionguid);
return E_POINTER;
dump_fmt(fmt);
if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE)
return E_INVALIDARG;
if (flags & ~(AUDCLNT_STREAMFLAGS_CROSSPROCESS |
AUDCLNT_STREAMFLAGS_LOOPBACK |
AUDCLNT_STREAMFLAGS_EVENTCALLBACK |
AUDCLNT_STREAMFLAGS_NOPERSIST |
AUDCLNT_STREAMFLAGS_RATEADJUST |
AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED |
AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE |
AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED |
AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY |
AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM)) {
FIXME("Unknown flags: %08lx\n", flags);
return E_INVALIDARG;
}
if (FAILED(params.result = adjust_timing(This, &duration, &period, mode, flags, fmt)))
return params.result;
sessions_lock();
if (This->stream) {
sessions_unlock();
return AUDCLNT_E_ALREADY_INITIALIZED;
}
if (FAILED(params.result = main_loop_start())) {
sessions_unlock();
return params.result;
}
params.name = name = get_application_name();
params.device = This->device_name;
params.flow = This->dataflow;
params.share = mode;
params.flags = flags;
params.duration = duration;
params.period = period;
params.fmt = fmt;
params.channel_count = &channel_count;
params.stream = &stream;
wine_unix_call(create_stream, &params);
free(name);
if (FAILED(params.result)) {
sessions_unlock();
return params.result;
}
if (!(This->vols = malloc(channel_count * sizeof(*This->vols)))) {
params.result = E_OUTOFMEMORY;
goto exit;
}
for (i = 0; i < channel_count; i++)
This->vols[i] = 1.f;
params.result = get_audio_session(sessionguid, This->parent, channel_count, &This->session);
exit:
if (FAILED(params.result)) {
stream_release(stream, NULL);
free(This->vols);
This->vols = NULL;
} else {
list_add_tail(&This->session->clients, &This->entry);
This->stream = stream;
This->channel_count = channel_count;
set_stream_volumes(This);
}
sessions_unlock();
return params.result;
} }
static HRESULT WINAPI client_GetBufferSize(IAudioClient3 *iface, UINT32 *out) static HRESULT WINAPI client_GetBufferSize(IAudioClient3 *iface, UINT32 *out)
...@@ -990,17 +1002,23 @@ static HRESULT WINAPI client_GetSharedModeEnginePeriod(IAudioClient3 *iface, ...@@ -990,17 +1002,23 @@ static HRESULT WINAPI client_GetSharedModeEnginePeriod(IAudioClient3 *iface,
UINT32 *max_period_frames) UINT32 *max_period_frames)
{ {
struct audio_client *This = impl_from_IAudioClient3(iface); struct audio_client *This = impl_from_IAudioClient3(iface);
FIXME("(%p)->(%p, %p, %p, %p, %p) - partial stub\n", REFERENCE_TIME def_period, min_period;
HRESULT hr;
TRACE("(%p)->(%p, %p, %p, %p, %p)\n",
This, format, default_period_frames, This, format, default_period_frames,
unit_period_frames, min_period_frames, unit_period_frames, min_period_frames,
max_period_frames); max_period_frames);
*default_period_frames = if (FAILED(hr = get_periods(This, &def_period, &min_period)))
*min_period_frames = return hr;
*max_period_frames =
format->nSamplesPerSec / 100; /* ~10ms */ *default_period_frames = def_period * format->nSamplesPerSec / (REFERENCE_TIME)10000000;
*unit_period_frames = 1; *min_period_frames = min_period * format->nSamplesPerSec / (REFERENCE_TIME)10000000;
return S_OK; *max_period_frames = *default_period_frames;
*unit_period_frames = 1;
return hr;
} }
static HRESULT WINAPI client_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface, static HRESULT WINAPI client_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface,
...@@ -1008,8 +1026,21 @@ static HRESULT WINAPI client_GetCurrentSharedModeEnginePeriod(IAudioClient3 *ifa ...@@ -1008,8 +1026,21 @@ static HRESULT WINAPI client_GetCurrentSharedModeEnginePeriod(IAudioClient3 *ifa
UINT32 *cur_period_frames) UINT32 *cur_period_frames)
{ {
struct audio_client *This = impl_from_IAudioClient3(iface); struct audio_client *This = impl_from_IAudioClient3(iface);
FIXME("(%p)->(%p, %p) - stub\n", This, cur_format, cur_period_frames); UINT32 dummy;
return E_NOTIMPL; HRESULT hr;
TRACE("(%p)->(%p, %p)\n", This, cur_format, cur_period_frames);
if (!cur_format || !cur_period_frames)
return E_POINTER;
if (FAILED(hr = client_GetMixFormat(iface, cur_format)))
return hr;
if (FAILED(hr = client_GetSharedModeEnginePeriod(iface, *cur_format, cur_period_frames, &dummy, &dummy, &dummy)))
return hr;
return hr;
} }
static HRESULT WINAPI client_InitializeSharedAudioStream(IAudioClient3 *iface, DWORD flags, static HRESULT WINAPI client_InitializeSharedAudioStream(IAudioClient3 *iface, DWORD flags,
...@@ -1018,14 +1049,16 @@ static HRESULT WINAPI client_InitializeSharedAudioStream(IAudioClient3 *iface, D ...@@ -1018,14 +1049,16 @@ static HRESULT WINAPI client_InitializeSharedAudioStream(IAudioClient3 *iface, D
const GUID *session_guid) const GUID *session_guid)
{ {
struct audio_client *This = impl_from_IAudioClient3(iface); struct audio_client *This = impl_from_IAudioClient3(iface);
REFERENCE_TIME duration; REFERENCE_TIME period;
FIXME("(%p)->(0x%lx, %u, %p, %s) - partial stub\n", This, flags, period_frames, format, debugstr_guid(session_guid));
TRACE("(%p)->(0x%lx, %u, %p, %s)\n", This, flags, period_frames, format, debugstr_guid(session_guid));
if (!format) if (!format)
return E_POINTER; return E_POINTER;
duration = period_frames * (REFERENCE_TIME)10000000 / format->nSamplesPerSec; period = period_frames * (REFERENCE_TIME)10000000 / format->nSamplesPerSec;
return client_Initialize(iface, AUDCLNT_SHAREMODE_SHARED, flags, duration, 0, format, session_guid);
return stream_init(This, FALSE, AUDCLNT_SHAREMODE_SHARED, flags, 0, period, format, session_guid);
} }
const IAudioClient3Vtbl AudioClient3_Vtbl = const IAudioClient3Vtbl AudioClient3_Vtbl =
......
...@@ -159,7 +159,7 @@ static HRESULT load_typelib(void) ...@@ -159,7 +159,7 @@ static HRESULT load_typelib(void)
if(typelib) if(typelib)
return S_OK; return S_OK;
hres = LoadRegTypeLib(&LIBID_ADODB, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); hres = LoadRegTypeLib(&LIBID_ADODB, 2, 8, LOCALE_SYSTEM_DEFAULT, &tl);
if(FAILED(hres)) { if(FAILED(hres)) {
ERR("LoadRegTypeLib failed: %08lx\n", hres); ERR("LoadRegTypeLib failed: %08lx\n", hres);
return hres; return hres;
......
...@@ -190,6 +190,13 @@ static void test_Locate(void) ...@@ -190,6 +190,13 @@ static void test_Locate(void)
if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n"); if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
bo.biHeight = - bo.biHeight; bo.biHeight = - bo.biHeight;
bo.biCompression = mmioFOURCC('U','Y','V','Y');
bo.biBitCount = bi.biBitCount = 16;
h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
ok(h == 0, "cvid->UYVY succeeded\n");
if (h) ok(ICClose(h) == ICERR_OK,"ICClose failed\n");
bo.biCompression = BI_RGB;
bo.biBitCount = bi.biBitCount = 32; bo.biBitCount = bi.biBitCount = 32;
h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS); h = ICLocate(ICTYPE_VIDEO, 0, &bi, &bo, ICMODE_DECOMPRESS);
ok(h != 0, "cvid->RGB32 failed\n"); ok(h != 0, "cvid->RGB32 failed\n");
......
...@@ -2125,14 +2125,31 @@ static void test_init_block(void) ...@@ -2125,14 +2125,31 @@ static void test_init_block(void)
} }
static DWORD WINAPI iosb_delayed_write_thread(void *arg)
{
HANDLE client = arg;
DWORD size;
BOOL ret;
Sleep(100);
ret = WriteFile( client, "data", sizeof("data"), &size, NULL );
ok( ret == TRUE, "got error %lu\n", GetLastError() );
return 0;
}
static void test_iosb(void) static void test_iosb(void)
{ {
static const char pipe_name[] = "\\\\.\\pipe\\wow64iosbnamedpipe"; static const char pipe_name[] = "\\\\.\\pipe\\wow64iosbnamedpipe";
HANDLE client, server; HANDLE client, server, thread;
NTSTATUS status; NTSTATUS status;
ULONG64 func; ULONG64 read_func, flush_func;
DWORD id;
IO_STATUS_BLOCK iosb32; IO_STATUS_BLOCK iosb32;
char buffer[6];
DWORD size;
BOOL ret;
struct struct
{ {
union union
...@@ -2142,66 +2159,89 @@ static void test_iosb(void) ...@@ -2142,66 +2159,89 @@ static void test_iosb(void)
}; };
ULONG64 Information; ULONG64 Information;
} iosb64; } iosb64;
ULONG64 args[] = { 0, 0, 0, 0, (ULONG_PTR)&iosb64, FSCTL_PIPE_LISTEN, 0, 0, 0, 0 }; ULONG64 args[] = { 0, 0, 0, 0, (ULONG_PTR)&iosb64, (ULONG_PTR)buffer, sizeof(buffer), 0, 0 };
ULONG64 flush_args[] = { 0, (ULONG_PTR)&iosb64 };
if (!is_wow64) return; if (!is_wow64) return;
if (!code_mem) return; if (!code_mem) return;
if (!ntdll_module) return; if (!ntdll_module) return;
func = get_proc_address64( ntdll_module, "NtFsControlFile" ); read_func = get_proc_address64( ntdll_module, "NtReadFile" );
flush_func = get_proc_address64( ntdll_module, "NtFlushBuffersFile" );
/* async calls set iosb32 but not iosb64 */ /* async calls set iosb32 but not iosb64 */
server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
4, 1024, 1024, 1000, NULL ); 4, 1024, 1024, 1000, NULL );
ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() ); ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() );
client = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING, NULL );
ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
memset( buffer, 0xcc, sizeof(buffer) );
memset( &iosb32, 0x55, sizeof(iosb32) ); memset( &iosb32, 0x55, sizeof(iosb32) );
iosb64.Pointer = PtrToUlong( &iosb32 ); iosb64.Pointer = PtrToUlong( &iosb32 );
iosb64.Information = 0xdeadbeef; iosb64.Information = 0xdeadbeef;
args[0] = (LONG_PTR)server; args[0] = (LONG_PTR)server;
status = call_func64( func, ARRAY_SIZE(args), args ); status = call_func64( read_func, ARRAY_SIZE(args), args );
ok( status == STATUS_PENDING, "NtFsControlFile returned %lx\n", status ); ok( status == STATUS_PENDING, "NtReadFile returned %lx\n", status );
ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status ); ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
ok( iosb64.Pointer == PtrToUlong(&iosb32), "status changed to %lx\n", iosb64.Status ); ok( iosb64.Pointer == PtrToUlong(&iosb32), "pointer changed to %I64x\n", iosb64.Pointer );
ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information ); ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
client = CreateFileA( pipe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, ret = WriteFile( client, "data", sizeof("data"), &size, NULL );
FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); ok( ret == TRUE, "got error %lu\n", GetLastError() );
ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
ok( iosb32.Status == 0, "Wrong iostatus %lx\n", iosb32.Status ); ok( iosb32.Status == 0, "Wrong iostatus %lx\n", iosb32.Status );
ok( iosb64.Pointer == PtrToUlong(&iosb32), "status changed to %lx\n", iosb64.Status ); ok( iosb32.Information == sizeof("data"), "Wrong information %Ix\n", iosb32.Information );
ok( iosb64.Pointer == PtrToUlong(&iosb32), "pointer changed to %I64x\n", iosb64.Pointer );
ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information ); ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
ok( !memcmp( buffer, "data", iosb32.Information ),
"got wrong data %s\n", debugstr_an(buffer, iosb32.Information) );
memset( buffer, 0xcc, sizeof(buffer) );
memset( &iosb32, 0x55, sizeof(iosb32) ); memset( &iosb32, 0x55, sizeof(iosb32) );
iosb64.Pointer = PtrToUlong( &iosb32 ); iosb64.Pointer = PtrToUlong( &iosb32 );
iosb64.Information = 0xdeadbeef; iosb64.Information = 0xdeadbeef;
id = 0xdeadbeef;
args[5] = FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE; ret = WriteFile( client, "data", sizeof("data"), &size, NULL );
args[6] = (ULONG_PTR)"ClientProcessId"; ok( ret == TRUE, "got error %lu\n", GetLastError() );
args[7] = sizeof("ClientProcessId");
args[8] = (ULONG_PTR)&id;
args[9] = sizeof(id);
status = call_func64( func, ARRAY_SIZE(args), args ); status = call_func64( read_func, ARRAY_SIZE(args), args );
ok( status == STATUS_PENDING || status == STATUS_SUCCESS, "NtFsControlFile returned %lx\n", status ); ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status );
todo_wine todo_wine
{ {
ok( iosb32.Status == STATUS_SUCCESS, "status changed to %lx\n", iosb32.Status ); ok( iosb32.Status == STATUS_SUCCESS, "status changed to %lx\n", iosb32.Status );
ok( iosb32.Information == sizeof(id), "info changed to %Ix\n", iosb32.Information ); ok( iosb32.Information == sizeof("data"), "info changed to %lx\n", iosb32.Information );
ok( iosb64.Pointer == PtrToUlong(&iosb32), "status changed to %lx\n", iosb64.Status ); ok( iosb64.Pointer == PtrToUlong(&iosb32), "pointer changed to %I64x\n", iosb64.Pointer );
ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information ); ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
if (iosb32.Information == sizeof("data"))
ok( !memcmp( buffer, "data", iosb32.Information ),
"got wrong data %s\n", debugstr_an(buffer, iosb32.Information) );
} }
ok( id == GetCurrentProcessId(), "wrong id %lx / %lx\n", id, GetCurrentProcessId() );
/* syscalls which are always synchronous set iosb64 but not iosb32 */
memset( &iosb32, 0x55, sizeof(iosb32) );
iosb64.Pointer = PtrToUlong( &iosb32 );
iosb64.Information = 0xdeadbeef;
flush_args[0] = (LONG_PTR)server;
status = call_func64( flush_func, ARRAY_SIZE(flush_args), flush_args );
ok( status == STATUS_SUCCESS, "NtFlushBuffersFile returned %lx\n", status );
ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
ok( iosb32.Information == 0x55555555, "info changed to %lx\n", iosb32.Information );
ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer );
ok( iosb64.Information == 0, "info changed to %lx\n", (ULONG_PTR)iosb64.Information );
CloseHandle( client ); CloseHandle( client );
CloseHandle( server ); CloseHandle( server );
/* synchronous calls set iosb64 but not iosb32 */ /* synchronous calls set iosb64 but not iosb32 */
server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND, server = CreateNamedPipeA( pipe_name, PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
4, 1024, 1024, 1000, NULL ); 4, 1024, 1024, 1000, NULL );
ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() ); ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() );
...@@ -2210,19 +2250,60 @@ static void test_iosb(void) ...@@ -2210,19 +2250,60 @@ static void test_iosb(void)
FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL ); FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL );
ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() ); ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
ret = WriteFile( client, "data", sizeof("data"), &size, NULL );
ok( ret == TRUE, "got error %lu\n", GetLastError() );
memset( buffer, 0xcc, sizeof(buffer) );
memset( &iosb32, 0x55, sizeof(iosb32) );
iosb64.Pointer = PtrToUlong( &iosb32 );
iosb64.Information = 0xdeadbeef;
args[0] = (LONG_PTR)server;
status = call_func64( read_func, ARRAY_SIZE(args), args );
ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status );
ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
ok( iosb32.Information == 0x55555555, "info changed to %lx\n", iosb32.Information );
ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer );
ok( iosb64.Information == sizeof("data"), "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
ok( !memcmp( buffer, "data", iosb64.Information ),
"got wrong data %s\n", debugstr_an(buffer, iosb64.Information) );
thread = CreateThread( NULL, 0, iosb_delayed_write_thread, client, 0, NULL );
memset( buffer, 0xcc, sizeof(buffer) );
memset( &iosb32, 0x55, sizeof(iosb32) ); memset( &iosb32, 0x55, sizeof(iosb32) );
iosb64.Pointer = PtrToUlong( &iosb32 ); iosb64.Pointer = PtrToUlong( &iosb32 );
iosb64.Information = 0xdeadbeef; iosb64.Information = 0xdeadbeef;
id = 0xdeadbeef;
args[0] = (LONG_PTR)server; args[0] = (LONG_PTR)server;
status = call_func64( func, ARRAY_SIZE(args), args ); status = call_func64( read_func, ARRAY_SIZE(args), args );
ok( status == STATUS_SUCCESS, "NtFsControlFile returned %lx\n", status ); ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status );
todo_wine
{
ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
ok( iosb32.Information == 0x55555555, "info changed to %lx\n", iosb32.Information );
ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer );
ok( iosb64.Information == sizeof("data"), "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
ok( !memcmp( buffer, "data", iosb64.Information ),
"got wrong data %s\n", debugstr_an(buffer, iosb64.Information) );
}
ret = WaitForSingleObject( thread, 1000 );
ok(!ret, "got %d\n", ret );
CloseHandle( thread );
memset( &iosb32, 0x55, sizeof(iosb32) );
iosb64.Pointer = PtrToUlong( &iosb32 );
iosb64.Information = 0xdeadbeef;
flush_args[0] = (LONG_PTR)server;
status = call_func64( flush_func, ARRAY_SIZE(flush_args), flush_args );
ok( status == STATUS_SUCCESS, "NtFlushBuffersFile returned %lx\n", status );
ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status ); ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
ok( iosb32.Information == 0x55555555, "info changed to %Ix\n", iosb32.Information ); ok( iosb32.Information == 0x55555555, "info changed to %lx\n", iosb32.Information );
ok( iosb64.Pointer == STATUS_SUCCESS, "status changed to %lx\n", iosb64.Status ); ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer );
ok( iosb64.Information == sizeof(id), "info changed to %Ix\n", (ULONG_PTR)iosb64.Information ); ok( iosb64.Information == 0, "info changed to %lx\n", (ULONG_PTR)iosb64.Information );
ok( id == GetCurrentProcessId(), "wrong id %lx / %lx\n", id, GetCurrentProcessId() );
CloseHandle( client ); CloseHandle( client );
CloseHandle( server ); CloseHandle( server );
} }
......
...@@ -234,6 +234,10 @@ SQLRETURN WINAPI SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, ...@@ -234,6 +234,10 @@ SQLRETURN WINAPI SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber,
return SQL_ERROR; return SQL_ERROR;
} }
if (!alloc_binding( &handle->bind_col, SQL_PARAM_INPUT_OUTPUT, ColumnNumber, handle->row_count )) return SQL_ERROR; if (!alloc_binding( &handle->bind_col, SQL_PARAM_INPUT_OUTPUT, ColumnNumber, handle->row_count )) return SQL_ERROR;
handle->bind_col.param[i].col.target_type = TargetType;
handle->bind_col.param[i].col.target_value = TargetValue;
handle->bind_col.param[i].col.buffer_length = BufferLength;
params.StatementHandle = handle->unix_handle; params.StatementHandle = handle->unix_handle;
if (StrLen_or_Ind) params.StrLen_or_Ind = handle->bind_col.param[i].len; if (StrLen_or_Ind) params.StrLen_or_Ind = handle->bind_col.param[i].len;
if (SUCCESS(( ret = ODBC_CALL( SQLBindCol, &params )))) handle->bind_col.param[i].ptr = StrLen_or_Ind; if (SUCCESS(( ret = ODBC_CALL( SQLBindCol, &params )))) handle->bind_col.param[i].ptr = StrLen_or_Ind;
...@@ -274,6 +278,11 @@ SQLRETURN WINAPI SQLBindParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNu ...@@ -274,6 +278,11 @@ SQLRETURN WINAPI SQLBindParam(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNu
return SQL_ERROR; return SQL_ERROR;
} }
if (!alloc_binding( &handle->bind_param, SQL_PARAM_INPUT, ParameterNumber, handle->row_count )) return SQL_ERROR; if (!alloc_binding( &handle->bind_param, SQL_PARAM_INPUT, ParameterNumber, handle->row_count )) return SQL_ERROR;
handle->bind_param.param[i].param.value_type = ValueType;
handle->bind_param.param[i].param.parameter_type = ParameterType;
handle->bind_param.param[i].param.length_precision = LengthPrecision;
handle->bind_param.param[i].param.parameter_scale = ParameterScale;
handle->bind_param.param[i].param.parameter_value = ParameterValue;
params.StatementHandle = handle->unix_handle; params.StatementHandle = handle->unix_handle;
params.StrLen_or_Ind = handle->bind_param.param[i].len; params.StrLen_or_Ind = handle->bind_param.param[i].len;
...@@ -1376,20 +1385,76 @@ static BOOL resize_result_lengths( struct handle *handle, UINT size ) ...@@ -1376,20 +1385,76 @@ static BOOL resize_result_lengths( struct handle *handle, UINT size )
UINT i; UINT i;
for (i = 0; i < handle->bind_col.count; i++) for (i = 0; i < handle->bind_col.count; i++)
{ {
UINT8 *tmp = realloc( handle->bind_col.param[i].len, size * sizeof(UINT64) ); UINT8 *tmp;
if (!tmp) return FALSE; if (!handle->bind_col.param[i].ptr) continue;
if (!(tmp = realloc( handle->bind_col.param[i].len, size * sizeof(UINT64) ))) return FALSE;
if (tmp != handle->bind_col.param[i].len)
{
struct SQLBindCol_params params;
params.StatementHandle = handle->unix_handle;
params.ColumnNumber = i + 1;
params.TargetType = handle->bind_col.param[i].col.target_type;
params.TargetValue = handle->bind_col.param[i].col.target_value;
params.BufferLength = handle->bind_col.param[i].col.buffer_length;
params.StrLen_or_Ind = tmp;
if (!SUCCESS(ODBC_CALL( SQLBindCol, &params )))
{
free( tmp );
return FALSE;
}
}
handle->bind_col.param[i].len = tmp; handle->bind_col.param[i].len = tmp;
} }
for (i = 0; i < handle->bind_param.count; i++) for (i = 0; i < handle->bind_param.count; i++)
{ {
UINT8 *tmp = realloc( handle->bind_param.param[i].len, size * sizeof(UINT64) ); UINT8 *tmp;
if (!tmp) return FALSE; if (!handle->bind_param.param[i].ptr) continue;
if (!(tmp = realloc( handle->bind_param.param[i].len, size * sizeof(UINT64) ))) return FALSE;
if (tmp != handle->bind_param.param[i].len)
{
struct SQLBindParam_params params;
params.StatementHandle = handle->unix_handle;
params.ParameterNumber = i + 1;
params.ValueType = handle->bind_param.param[i].param.value_type;
params.ParameterType = handle->bind_param.param[i].param.parameter_type;
params.LengthPrecision = handle->bind_param.param[i].param.length_precision;
params.ParameterScale = handle->bind_param.param[i].param.parameter_scale;
params.ParameterValue = handle->bind_param.param[i].param.parameter_value;
params.StrLen_or_Ind = tmp;
if (!SUCCESS(ODBC_CALL( SQLBindParam, &params )))
{
free( tmp );
return FALSE;
}
}
handle->bind_param.param[i].len = tmp; handle->bind_param.param[i].len = tmp;
} }
for (i = 0; i < handle->bind_parameter.count; i++) for (i = 0; i < handle->bind_parameter.count; i++)
{ {
UINT8 *tmp = realloc( handle->bind_parameter.param[i].len, size * sizeof(UINT64) ); UINT8 *tmp;
if (!tmp) return FALSE; if (!(tmp = realloc( handle->bind_parameter.param[i].len, size * sizeof(UINT64) ))) return FALSE;
if (tmp != handle->bind_parameter.param[i].len)
{
struct SQLBindParameter_params params;
params.StatementHandle = handle->unix_handle;
params.ParameterNumber = i + 1;
params.InputOutputType = handle->bind_parameter.param[i].parameter.input_output_type;
params.ValueType = handle->bind_parameter.param[i].parameter.value_type;
params.ParameterType = handle->bind_parameter.param[i].parameter.parameter_type;
params.ColumnSize = handle->bind_parameter.param[i].parameter.column_size;
params.DecimalDigits = handle->bind_parameter.param[i].parameter.decimal_digits;
params.ParameterValue = handle->bind_parameter.param[i].parameter.parameter_value;
params.BufferLength = handle->bind_parameter.param[i].parameter.buffer_length;
params.StrLen_or_Ind = tmp;
if (!SUCCESS(ODBC_CALL( SQLBindParameter, &params )))
{
free( tmp );
return FALSE;
}
}
handle->bind_parameter.param[i].len = tmp; handle->bind_parameter.param[i].len = tmp;
} }
return TRUE; return TRUE;
...@@ -1984,6 +2049,13 @@ SQLRETURN WINAPI SQLBindParameter(SQLHSTMT StatementHandle, SQLUSMALLINT Paramet ...@@ -1984,6 +2049,13 @@ SQLRETURN WINAPI SQLBindParameter(SQLHSTMT StatementHandle, SQLUSMALLINT Paramet
return SQL_ERROR; return SQL_ERROR;
} }
if (!alloc_binding( &handle->bind_parameter, InputOutputType, ParameterNumber, handle->row_count )) return SQL_ERROR; if (!alloc_binding( &handle->bind_parameter, InputOutputType, ParameterNumber, handle->row_count )) return SQL_ERROR;
handle->bind_parameter.param[i].parameter.input_output_type = InputOutputType;
handle->bind_parameter.param[i].parameter.value_type = ValueType;
handle->bind_parameter.param[i].parameter.parameter_type = ParameterType;
handle->bind_parameter.param[i].parameter.column_size = ColumnSize;
handle->bind_parameter.param[i].parameter.decimal_digits = DecimalDigits;
handle->bind_parameter.param[i].parameter.parameter_value = ParameterValue;
handle->bind_parameter.param[i].parameter.buffer_length = BufferLength;
params.StatementHandle = handle->unix_handle; params.StatementHandle = handle->unix_handle;
params.StrLen_or_Ind = handle->bind_parameter.param[i].len; params.StrLen_or_Ind = handle->bind_parameter.param[i].len;
......
...@@ -152,9 +152,42 @@ enum sql_funcs ...@@ -152,9 +152,42 @@ enum sql_funcs
unix_funcs_count unix_funcs_count
}; };
struct bind_col_args
{
INT16 target_type;
void *target_value;
INT64 buffer_length;
};
struct bind_param_args
{
INT16 value_type;
INT16 parameter_type;
UINT64 length_precision;
INT16 parameter_scale;
void *parameter_value;
};
struct bind_parameter_args
{
INT16 input_output_type;
INT16 value_type;
INT16 parameter_type;
UINT64 column_size;
INT16 decimal_digits;
void *parameter_value;
INT64 buffer_length;
};
struct param struct param
{ {
INT16 type; INT16 type;
union
{
struct bind_col_args col;
struct bind_param_args param;
struct bind_parameter_args parameter;
};
UINT8 *len; /* result length array stored in Unix lib */ UINT8 *len; /* result length array stored in Unix lib */
void *ptr; /* result length ptr passed by client */ void *ptr; /* result length ptr passed by client */
}; };
......
...@@ -181,6 +181,8 @@ my %manual_win_thunks = ...@@ -181,6 +181,8 @@ my %manual_win_thunks =
"wglGetExtensionsStringARB" => 1, "wglGetExtensionsStringARB" => 1,
"wglGetExtensionsStringEXT" => 1, "wglGetExtensionsStringEXT" => 1,
"wglGetPixelFormat" => 1, "wglGetPixelFormat" => 1,
"wglGetPixelFormatAttribfvARB" => 1,
"wglGetPixelFormatAttribivARB" => 1,
"wglGetProcAddress" => 1, "wglGetProcAddress" => 1,
"wglQueryCurrentRendererStringWINE" => 1, "wglQueryCurrentRendererStringWINE" => 1,
"wglQueryRendererStringWINE" => 1, "wglQueryRendererStringWINE" => 1,
...@@ -884,6 +886,31 @@ print HEADER "struct wgl_pbuffer;\n\n"; ...@@ -884,6 +886,31 @@ print HEADER "struct wgl_pbuffer;\n\n";
print HEADER "struct wgl_pixel_format\n"; print HEADER "struct wgl_pixel_format\n";
print HEADER "{\n"; print HEADER "{\n";
print HEADER " PIXELFORMATDESCRIPTOR pfd;\n"; print HEADER " PIXELFORMATDESCRIPTOR pfd;\n";
print HEADER " int swap_method;\n";
print HEADER " int transparent;\n";
print HEADER " int pixel_type;\n";
print HEADER " int draw_to_pbuffer;\n";
print HEADER " int max_pbuffer_pixels;\n";
print HEADER " int max_pbuffer_width;\n";
print HEADER " int max_pbuffer_height;\n";
print HEADER " int transparent_red_value;\n";
print HEADER " int transparent_red_value_valid;\n";
print HEADER " int transparent_green_value;\n";
print HEADER " int transparent_green_value_valid;\n";
print HEADER " int transparent_blue_value;\n";
print HEADER " int transparent_blue_value_valid;\n";
print HEADER " int transparent_alpha_value;\n";
print HEADER " int transparent_alpha_value_valid;\n";
print HEADER " int transparent_index_value;\n";
print HEADER " int transparent_index_value_valid;\n";
print HEADER " int sample_buffers;\n";
print HEADER " int samples;\n";
print HEADER " int bind_to_texture_rgb;\n";
print HEADER " int bind_to_texture_rgba;\n";
print HEADER " int bind_to_texture_rectangle_rgb;\n";
print HEADER " int bind_to_texture_rectangle_rgba;\n";
print HEADER " int framebuffer_srgb_capable;\n";
print HEADER " int float_components;\n";
print HEADER "};\n\n"; print HEADER "};\n\n";
print HEADER "struct opengl_funcs\n{\n"; print HEADER "struct opengl_funcs\n{\n";
......
...@@ -24217,24 +24217,6 @@ static HDC WINAPI wglGetPbufferDCARB( HPBUFFERARB hPbuffer ) ...@@ -24217,24 +24217,6 @@ static HDC WINAPI wglGetPbufferDCARB( HPBUFFERARB hPbuffer )
return args.ret; return args.ret;
} }
   
static BOOL WINAPI wglGetPixelFormatAttribfvARB( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues )
{
struct wglGetPixelFormatAttribfvARB_params args = { .teb = NtCurrentTeb(), .hdc = hdc, .iPixelFormat = iPixelFormat, .iLayerPlane = iLayerPlane, .nAttributes = nAttributes, .piAttributes = piAttributes, .pfValues = pfValues };
NTSTATUS status;
TRACE( "hdc %p, iPixelFormat %d, iLayerPlane %d, nAttributes %u, piAttributes %p, pfValues %p\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues );
if ((status = UNIX_CALL( wglGetPixelFormatAttribfvARB, &args ))) WARN( "wglGetPixelFormatAttribfvARB returned %#lx\n", status );
return args.ret;
}
static BOOL WINAPI wglGetPixelFormatAttribivARB( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues )
{
struct wglGetPixelFormatAttribivARB_params args = { .teb = NtCurrentTeb(), .hdc = hdc, .iPixelFormat = iPixelFormat, .iLayerPlane = iLayerPlane, .nAttributes = nAttributes, .piAttributes = piAttributes, .piValues = piValues };
NTSTATUS status;
TRACE( "hdc %p, iPixelFormat %d, iLayerPlane %d, nAttributes %u, piAttributes %p, piValues %p\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues );
if ((status = UNIX_CALL( wglGetPixelFormatAttribivARB, &args ))) WARN( "wglGetPixelFormatAttribivARB returned %#lx\n", status );
return args.ret;
}
static int WINAPI wglGetSwapIntervalEXT(void) static int WINAPI wglGetSwapIntervalEXT(void)
{ {
struct wglGetSwapIntervalEXT_params args = { .teb = NtCurrentTeb() }; struct wglGetSwapIntervalEXT_params args = { .teb = NtCurrentTeb() };
...@@ -24340,6 +24322,8 @@ extern GLboolean WINAPI glUnmapNamedBufferEXT( GLuint buffer ); ...@@ -24340,6 +24322,8 @@ extern GLboolean WINAPI glUnmapNamedBufferEXT( GLuint buffer );
extern HDC WINAPI wglGetCurrentReadDCARB(void); extern HDC WINAPI wglGetCurrentReadDCARB(void);
extern const char * WINAPI wglGetExtensionsStringARB( HDC hdc ); extern const char * WINAPI wglGetExtensionsStringARB( HDC hdc );
extern const char * WINAPI wglGetExtensionsStringEXT(void); extern const char * WINAPI wglGetExtensionsStringEXT(void);
extern BOOL WINAPI wglGetPixelFormatAttribfvARB( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues );
extern BOOL WINAPI wglGetPixelFormatAttribivARB( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues );
extern const GLchar * WINAPI wglQueryCurrentRendererStringWINE( GLenum attribute ); extern const GLchar * WINAPI wglQueryCurrentRendererStringWINE( GLenum attribute );
extern const GLchar * WINAPI wglQueryRendererStringWINE( HDC dc, GLint renderer, GLenum attribute ); extern const GLchar * WINAPI wglQueryRendererStringWINE( HDC dc, GLint renderer, GLenum attribute );
const void *extension_procs[] = const void *extension_procs[] =
...@@ -322,7 +322,9 @@ static struct wgl_pixel_format *get_pixel_formats( HDC hdc, UINT *num_formats, ...@@ -322,7 +322,9 @@ static struct wgl_pixel_format *get_pixel_formats( HDC hdc, UINT *num_formats,
} }
if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error; if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error;
if (!(args.formats = malloc( sizeof(*args.formats) * args.num_formats ))) goto error; /* Clear formats memory since not all drivers deal with all wgl_pixel_format
* fields at the moment. */
if (!(args.formats = calloc( args.num_formats, sizeof(*args.formats) ))) goto error;
args.max_formats = args.num_formats; args.max_formats = args.num_formats;
if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error; if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error;
...@@ -343,6 +345,153 @@ error: ...@@ -343,6 +345,153 @@ error:
return NULL; return NULL;
} }
static BOOL wgl_attrib_uses_layer( int attrib )
{
switch (attrib)
{
case WGL_ACCELERATION_ARB:
case WGL_TRANSPARENT_ARB:
case WGL_SHARE_DEPTH_ARB:
case WGL_SHARE_STENCIL_ARB:
case WGL_SHARE_ACCUM_ARB:
case WGL_TRANSPARENT_RED_VALUE_ARB:
case WGL_TRANSPARENT_GREEN_VALUE_ARB:
case WGL_TRANSPARENT_BLUE_VALUE_ARB:
case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
case WGL_TRANSPARENT_INDEX_VALUE_ARB:
case WGL_SUPPORT_GDI_ARB:
case WGL_SUPPORT_OPENGL_ARB:
case WGL_DOUBLE_BUFFER_ARB:
case WGL_STEREO_ARB:
case WGL_PIXEL_TYPE_ARB:
case WGL_COLOR_BITS_ARB:
case WGL_RED_BITS_ARB:
case WGL_RED_SHIFT_ARB:
case WGL_GREEN_BITS_ARB:
case WGL_GREEN_SHIFT_ARB:
case WGL_BLUE_BITS_ARB:
case WGL_BLUE_SHIFT_ARB:
case WGL_ALPHA_BITS_ARB:
case WGL_ALPHA_SHIFT_ARB:
case WGL_ACCUM_BITS_ARB:
case WGL_ACCUM_RED_BITS_ARB:
case WGL_ACCUM_GREEN_BITS_ARB:
case WGL_ACCUM_BLUE_BITS_ARB:
case WGL_ACCUM_ALPHA_BITS_ARB:
case WGL_DEPTH_BITS_ARB:
case WGL_STENCIL_BITS_ARB:
case WGL_AUX_BUFFERS_ARB:
case WGL_SAMPLE_BUFFERS_ARB:
case WGL_SAMPLES_ARB:
case WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB:
case WGL_FLOAT_COMPONENTS_NV:
return TRUE;
default:
return FALSE;
}
}
static BOOL wgl_pixel_format_get_attrib( const struct wgl_pixel_format *fmt, int attrib, int *value )
{
int val = 0;
int valid = -1;
switch (attrib)
{
case WGL_DRAW_TO_WINDOW_ARB: val = !!(fmt->pfd.dwFlags & PFD_DRAW_TO_WINDOW); break;
case WGL_DRAW_TO_BITMAP_ARB: val = !!(fmt->pfd.dwFlags & PFD_DRAW_TO_BITMAP); break;
case WGL_ACCELERATION_ARB:
if (fmt->pfd.dwFlags & PFD_GENERIC_ACCELERATED)
val = WGL_GENERIC_ACCELERATION_ARB;
else if (fmt->pfd.dwFlags & PFD_GENERIC_FORMAT)
val = WGL_NO_ACCELERATION_ARB;
else
val = WGL_FULL_ACCELERATION_ARB;
break;
case WGL_NEED_PALETTE_ARB: val = !!(fmt->pfd.dwFlags & PFD_NEED_PALETTE); break;
case WGL_NEED_SYSTEM_PALETTE_ARB: val = !!(fmt->pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE); break;
case WGL_SWAP_LAYER_BUFFERS_ARB: val = !!(fmt->pfd.dwFlags & PFD_SWAP_LAYER_BUFFERS); break;
case WGL_SWAP_METHOD_ARB: val = fmt->swap_method; break;
case WGL_NUMBER_OVERLAYS_ARB:
case WGL_NUMBER_UNDERLAYS_ARB:
/* We don't support any overlays/underlays. */
val = 0;
break;
case WGL_TRANSPARENT_ARB: val = fmt->transparent; break;
case WGL_SHARE_DEPTH_ARB:
case WGL_SHARE_STENCIL_ARB:
case WGL_SHARE_ACCUM_ARB:
/* We support only a main plane at the moment which by definition
* shares the depth/stencil/accum buffers with itself. */
val = GL_TRUE;
break;
case WGL_SUPPORT_GDI_ARB: val = !!(fmt->pfd.dwFlags & PFD_SUPPORT_GDI); break;
case WGL_SUPPORT_OPENGL_ARB: val = !!(fmt->pfd.dwFlags & PFD_SUPPORT_OPENGL); break;
case WGL_DOUBLE_BUFFER_ARB: val = !!(fmt->pfd.dwFlags & PFD_DOUBLEBUFFER); break;
case WGL_STEREO_ARB: val = !!(fmt->pfd.dwFlags & PFD_STEREO); break;
case WGL_PIXEL_TYPE_ARB: val = fmt->pixel_type; break;
case WGL_COLOR_BITS_ARB: val = fmt->pfd.cColorBits; break;
case WGL_RED_BITS_ARB: val = fmt->pfd.cRedBits; break;
case WGL_RED_SHIFT_ARB: val = fmt->pfd.cRedShift; break;
case WGL_GREEN_BITS_ARB: val = fmt->pfd.cGreenBits; break;
case WGL_GREEN_SHIFT_ARB: val = fmt->pfd.cGreenShift; break;
case WGL_BLUE_BITS_ARB: val = fmt->pfd.cBlueBits; break;
case WGL_BLUE_SHIFT_ARB: val = fmt->pfd.cBlueShift; break;
case WGL_ALPHA_BITS_ARB: val = fmt->pfd.cAlphaBits; break;
case WGL_ALPHA_SHIFT_ARB: val = fmt->pfd.cAlphaShift; break;
case WGL_ACCUM_BITS_ARB: val = fmt->pfd.cAccumBits; break;
case WGL_ACCUM_RED_BITS_ARB: val = fmt->pfd.cAccumRedBits; break;
case WGL_ACCUM_GREEN_BITS_ARB: val = fmt->pfd.cAccumGreenBits; break;
case WGL_ACCUM_BLUE_BITS_ARB: val = fmt->pfd.cAccumBlueBits; break;
case WGL_ACCUM_ALPHA_BITS_ARB: val = fmt->pfd.cAccumAlphaBits; break;
case WGL_DEPTH_BITS_ARB: val = fmt->pfd.cDepthBits; break;
case WGL_STENCIL_BITS_ARB: val = fmt->pfd.cStencilBits; break;
case WGL_AUX_BUFFERS_ARB: val = fmt->pfd.cAuxBuffers; break;
case WGL_DRAW_TO_PBUFFER_ARB: val = fmt->draw_to_pbuffer; break;
case WGL_MAX_PBUFFER_PIXELS_ARB: val = fmt->max_pbuffer_pixels; break;
case WGL_MAX_PBUFFER_WIDTH_ARB: val = fmt->max_pbuffer_width; break;
case WGL_MAX_PBUFFER_HEIGHT_ARB: val = fmt->max_pbuffer_height; break;
case WGL_TRANSPARENT_RED_VALUE_ARB:
val = fmt->transparent_red_value;
valid = !!fmt->transparent_red_value_valid;
break;
case WGL_TRANSPARENT_GREEN_VALUE_ARB:
val = fmt->transparent_green_value;
valid = !!fmt->transparent_green_value_valid;
break;
case WGL_TRANSPARENT_BLUE_VALUE_ARB:
val = fmt->transparent_blue_value;
valid = !!fmt->transparent_blue_value_valid;
break;
case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
val = fmt->transparent_alpha_value;
valid = !!fmt->transparent_alpha_value_valid;
break;
case WGL_TRANSPARENT_INDEX_VALUE_ARB:
val = fmt->transparent_index_value;
valid = !!fmt->transparent_index_value_valid;
break;
case WGL_SAMPLE_BUFFERS_ARB: val = fmt->sample_buffers; break;
case WGL_SAMPLES_ARB: val = fmt->samples; break;
case WGL_BIND_TO_TEXTURE_RGB_ARB: val = fmt->bind_to_texture_rgb; break;
case WGL_BIND_TO_TEXTURE_RGBA_ARB: val = fmt->bind_to_texture_rgba; break;
case WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV: val = fmt->bind_to_texture_rectangle_rgb; break;
case WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV: val = fmt->bind_to_texture_rectangle_rgba; break;
case WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB: val = fmt->framebuffer_srgb_capable; break;
case WGL_FLOAT_COMPONENTS_NV: val = fmt->float_components; break;
default:
FIXME( "unsupported 0x%x WGL attribute\n", attrib );
valid = 0;
break;
}
/* If we haven't already determined validity, use the default check */
if (valid == -1) valid = val != -1;
if (valid) *value = val;
return valid;
}
INT WINAPI wglDescribePixelFormat( HDC hdc, int index, UINT size, PIXELFORMATDESCRIPTOR *ppfd ) INT WINAPI wglDescribePixelFormat( HDC hdc, int index, UINT size, PIXELFORMATDESCRIPTOR *ppfd )
{ {
struct wgl_pixel_format *formats; struct wgl_pixel_format *formats;
...@@ -360,6 +509,102 @@ INT WINAPI wglDescribePixelFormat( HDC hdc, int index, UINT size, PIXELFORMATDES ...@@ -360,6 +509,102 @@ INT WINAPI wglDescribePixelFormat( HDC hdc, int index, UINT size, PIXELFORMATDES
return num_onscreen_formats; return num_onscreen_formats;
} }
/***********************************************************************
* wglGetPixelFormatAttribivARB (OPENGL32.@)
*/
BOOL WINAPI wglGetPixelFormatAttribivARB( HDC hdc, int index, int plane, UINT count,
const int *attributes, int *values )
{
static const DWORD invalid_data_error = 0xC007000D;
struct wgl_pixel_format *formats;
UINT i, num_formats, num_onscreen_formats;
TRACE( "hdc %p, index %d, plane %d, count %u, attributes %p, values %p\n",
hdc, index, plane, count, attributes, values );
formats = get_pixel_formats( hdc, &num_formats, &num_onscreen_formats );
/* If the driver doesn't yet provide ARB attrib information in
* wgl_pixel_format, fall back to an explicit call. */
if (num_formats && !formats[0].pixel_type)
{
struct wglGetPixelFormatAttribivARB_params args =
{
.teb = NtCurrentTeb(),
.hdc = hdc,
.iPixelFormat = index,
.iLayerPlane = plane,
.nAttributes = count,
.piAttributes = attributes,
.piValues = values
};
NTSTATUS status;
if ((status = UNIX_CALL( wglGetPixelFormatAttribivARB, &args )))
WARN( "wglGetPixelFormatAttribivARB returned %#lx\n", status );
return args.ret;
}
if (!count) return TRUE;
if (count == 1 && attributes[0] == WGL_NUMBER_PIXEL_FORMATS_ARB)
{
values[0] = num_formats;
return TRUE;
}
if (index <= 0 || index > num_formats)
{
SetLastError( invalid_data_error );
return FALSE;
}
for (i = 0; i < count; ++i)
{
int attrib = attributes[i];
if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB)
{
values[i] = num_formats;
}
else if ((plane != 0 && wgl_attrib_uses_layer( attrib )) ||
!wgl_pixel_format_get_attrib( &formats[index - 1], attrib, &values[i] ))
{
SetLastError( invalid_data_error );
return FALSE;
}
}
return TRUE;
}
/***********************************************************************
* wglGetPixelFormatAttribfvARB (OPENGL32.@)
*/
BOOL WINAPI wglGetPixelFormatAttribfvARB( HDC hdc, int index, int plane, UINT count,
const int *attributes, FLOAT *values )
{
int *ivalues;
BOOL ret;
UINT i;
TRACE( "hdc %p, index %d, plane %d, count %u, attributes %p, values %p\n",
hdc, index, plane, count, attributes, values );
if (!(ivalues = malloc( count * sizeof(int) ))) return FALSE;
/* For now we can piggy-back on wglGetPixelFormatAttribivARB, since we don't support
* any non-integer attributes. */
ret = wglGetPixelFormatAttribivARB( hdc, index, plane, count, attributes, ivalues );
if (ret)
{
for (i = 0; i < count; i++)
values[i] = ivalues[i];
}
free( ivalues );
return ret;
}
/*********************************************************************** /***********************************************************************
* wglGetPixelFormat (OPENGL32.@) * wglGetPixelFormat (OPENGL32.@)
*/ */
......
...@@ -48,6 +48,8 @@ struct avi_decompressor ...@@ -48,6 +48,8 @@ struct avi_decompressor
HIC hvid; HIC hvid;
BITMAPINFOHEADER* pBihIn; BITMAPINFOHEADER* pBihIn;
CRITICAL_SECTION late_cs;
REFERENCE_TIME late; REFERENCE_TIME late;
}; };
...@@ -77,7 +79,9 @@ static HRESULT avi_decompressor_sink_query_accept(struct strmbase_pin *iface, co ...@@ -77,7 +79,9 @@ static HRESULT avi_decompressor_sink_query_accept(struct strmbase_pin *iface, co
static HRESULT avi_decompressor_sink_end_flush(struct strmbase_sink *iface) static HRESULT avi_decompressor_sink_end_flush(struct strmbase_sink *iface)
{ {
struct avi_decompressor *filter = impl_from_strmbase_filter(iface->pin.filter); struct avi_decompressor *filter = impl_from_strmbase_filter(iface->pin.filter);
EnterCriticalSection(&filter->late_cs);
filter->late = -1; filter->late = -1;
LeaveCriticalSection(&filter->late_cs);
if (filter->source.pin.peer) if (filter->source.pin.peer)
return IPin_EndFlush(filter->source.pin.peer); return IPin_EndFlush(filter->source.pin.peer);
return S_OK; return S_OK;
...@@ -167,8 +171,10 @@ static HRESULT WINAPI avi_decompressor_sink_Receive(struct strmbase_sink *iface, ...@@ -167,8 +171,10 @@ static HRESULT WINAPI avi_decompressor_sink_Receive(struct strmbase_sink *iface,
if (IMediaSample_IsSyncPoint(pSample) != S_OK) if (IMediaSample_IsSyncPoint(pSample) != S_OK)
flags |= ICDECOMPRESS_NOTKEYFRAME; flags |= ICDECOMPRESS_NOTKEYFRAME;
hr = IMediaSample_GetTime(pSample, &tStart, &tStop); hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
EnterCriticalSection(&This->late_cs);
if (hr == S_OK && AVIDec_DropSample(This, tStart)) if (hr == S_OK && AVIDec_DropSample(This, tStart))
flags |= ICDECOMPRESS_HURRYUP; flags |= ICDECOMPRESS_HURRYUP;
LeaveCriticalSection(&This->late_cs);
res = ICDecompress(This->hvid, flags, This->pBihIn, pbSrcStream, &source_format->bmiHeader, pbDstStream); res = ICDecompress(This->hvid, flags, This->pBihIn, pbSrcStream, &source_format->bmiHeader, pbDstStream);
if (res != ICERR_OK) if (res != ICERR_OK)
...@@ -482,12 +488,13 @@ static HRESULT WINAPI avi_decompressor_source_qc_Notify(IQualityControl *iface, ...@@ -482,12 +488,13 @@ static HRESULT WINAPI avi_decompressor_source_qc_Notify(IQualityControl *iface,
TRACE("filter %p, sender %p, type %#x, proportion %ld, late %s, timestamp %s.\n", TRACE("filter %p, sender %p, type %#x, proportion %ld, late %s, timestamp %s.\n",
filter, sender, q.Type, q.Proportion, debugstr_time(q.Late), debugstr_time(q.TimeStamp)); filter, sender, q.Type, q.Proportion, debugstr_time(q.Late), debugstr_time(q.TimeStamp));
EnterCriticalSection(&filter->filter.stream_cs); /* can't take the stream CS here, Submarine Titans calls this function from a foreign thread while inside sink_Receive */
EnterCriticalSection(&filter->late_cs);
if (q.Late > 0) if (q.Late > 0)
filter->late = q.Late + q.TimeStamp; filter->late = q.Late + q.TimeStamp;
else else
filter->late = -1; filter->late = -1;
LeaveCriticalSection(&filter->filter.stream_cs); LeaveCriticalSection(&filter->late_cs);
return S_OK; return S_OK;
} }
...@@ -532,6 +539,9 @@ static void avi_decompressor_destroy(struct strmbase_filter *iface) ...@@ -532,6 +539,9 @@ static void avi_decompressor_destroy(struct strmbase_filter *iface)
IPin_Disconnect(filter->source.pin.peer); IPin_Disconnect(filter->source.pin.peer);
IPin_Disconnect(&filter->source.pin.IPin_iface); IPin_Disconnect(&filter->source.pin.IPin_iface);
filter->late_cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&filter->late_cs);
strmbase_sink_cleanup(&filter->sink); strmbase_sink_cleanup(&filter->sink);
strmbase_source_cleanup(&filter->source); strmbase_source_cleanup(&filter->source);
strmbase_passthrough_cleanup(&filter->passthrough); strmbase_passthrough_cleanup(&filter->passthrough);
...@@ -550,7 +560,9 @@ static HRESULT avi_decompressor_init_stream(struct strmbase_filter *iface) ...@@ -550,7 +560,9 @@ static HRESULT avi_decompressor_init_stream(struct strmbase_filter *iface)
if (!filter->source.pin.peer) if (!filter->source.pin.peer)
return S_OK; return S_OK;
EnterCriticalSection(&filter->late_cs);
filter->late = -1; filter->late = -1;
LeaveCriticalSection(&filter->late_cs);
source_format = (VIDEOINFOHEADER *)filter->source.pin.mt.pbFormat; source_format = (VIDEOINFOHEADER *)filter->source.pin.mt.pbFormat;
if ((res = ICDecompressBegin(filter->hvid, filter->pBihIn, &source_format->bmiHeader))) if ((res = ICDecompressBegin(filter->hvid, filter->pBihIn, &source_format->bmiHeader)))
...@@ -618,6 +630,9 @@ HRESULT avi_dec_create(IUnknown *outer, IUnknown **out) ...@@ -618,6 +630,9 @@ HRESULT avi_dec_create(IUnknown *outer, IUnknown **out)
ISeekingPassThru_Init(&object->passthrough.ISeekingPassThru_iface, FALSE, ISeekingPassThru_Init(&object->passthrough.ISeekingPassThru_iface, FALSE,
&object->sink.pin.IPin_iface); &object->sink.pin.IPin_iface);
InitializeCriticalSectionEx(&object->late_cs, 0, RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO);
object->late_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": object.late_cs");
TRACE("Created AVI decompressor %p.\n", object); TRACE("Created AVI decompressor %p.\n", object);
*out = &object->filter.IUnknown_inner; *out = &object->filter.IUnknown_inner;
......
...@@ -873,6 +873,20 @@ static HRESULT testsink_connect(struct strmbase_sink *iface, IPin *peer, const A ...@@ -873,6 +873,20 @@ static HRESULT testsink_connect(struct strmbase_sink *iface, IPin *peer, const A
return S_OK; return S_OK;
} }
static DWORD WINAPI call_qc_notify(void *ptr)
{
struct testfilter *filter = ptr;
IQualityControl *qc;
Quality q = { Famine, 2000, -10000000, 10000000 };
IPin_QueryInterface(filter->sink.pin.peer, &IID_IQualityControl, (void**)&qc);
/* don't worry too much about what it returns, just check that it doesn't deadlock */
IQualityControl_Notify(qc, &filter->filter.IBaseFilter_iface, q);
IQualityControl_Release(qc);
return 0;
}
static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample *sample) static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample *sample)
{ {
struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter); struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
...@@ -920,6 +934,13 @@ static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample ...@@ -920,6 +934,13 @@ static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample
hr = IMediaSample_IsSyncPoint(sample); hr = IMediaSample_IsSyncPoint(sample);
todo_wine_if (testmode == 5 || testmode == 6) ok(hr == S_OK, "Got hr %#lx.\n", hr); todo_wine_if (testmode == 5 || testmode == 6) ok(hr == S_OK, "Got hr %#lx.\n", hr);
if (testmode == 7)
{
HANDLE h = CreateThread(NULL, 0, call_qc_notify, filter, 0, NULL);
ok(WaitForSingleObject(h, 1000) == WAIT_OBJECT_0, "Didn't expect deadlock.\n");
CloseHandle(h);
}
return S_OK; return S_OK;
} }
...@@ -1129,6 +1150,15 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input, ...@@ -1129,6 +1150,15 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input,
ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(hr == S_OK, "Got hr %#lx.\n", hr);
todo_wine ok(!sink->got_sample, "Got %u calls to Receive().\n", sink->got_sample); todo_wine ok(!sink->got_sample, "Got %u calls to Receive().\n", sink->got_sample);
testmode = 7;
hr = IMediaSample_SetSyncPoint(sample, TRUE);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
sink->got_sample = 0;
hr = IMemInputPin_Receive(input, sample);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
ok(sink->got_sample == 1, "Got %u calls to Receive().\n", sink->got_sample);
sink->got_sample = 0;
hr = IMediaControl_Stop(control); hr = IMediaControl_Stop(control);
ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(hr == S_OK, "Got hr %#lx.\n", hr);
...@@ -1174,7 +1204,7 @@ static void test_streaming_events(IMediaControl *control, IPin *sink, ...@@ -1174,7 +1204,7 @@ static void test_streaming_events(IMediaControl *control, IPin *sink,
ok(!testsink->got_eos, "Got %u calls to IPin::EndOfStream().\n", testsink->got_eos); ok(!testsink->got_eos, "Got %u calls to IPin::EndOfStream().\n", testsink->got_eos);
hr = IPin_EndOfStream(sink); hr = IPin_EndOfStream(sink);
ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(hr == S_OK, "Got hr %#lx.\n", hr);
todo_wine ok(!testsink->got_sample, "Got %u calls to Receive().\n", testsink->got_sample); ok(!testsink->got_sample, "Got %u calls to Receive().\n", testsink->got_sample);
ok(testsink->got_eos == 1, "Got %u calls to IPin::EndOfStream().\n", testsink->got_eos); ok(testsink->got_eos == 1, "Got %u calls to IPin::EndOfStream().\n", testsink->got_eos);
testsink->got_eos = 0; testsink->got_eos = 0;
...@@ -1185,7 +1215,7 @@ static void test_streaming_events(IMediaControl *control, IPin *sink, ...@@ -1185,7 +1215,7 @@ static void test_streaming_events(IMediaControl *control, IPin *sink,
testmode = 0; testmode = 0;
hr = IMemInputPin_Receive(input, sample); hr = IMemInputPin_Receive(input, sample);
ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(hr == S_OK, "Got hr %#lx.\n", hr);
todo_wine ok(testsink->got_sample == 1, "Got %u calls to Receive().\n", testsink->got_sample); ok(testsink->got_sample == 1, "Got %u calls to Receive().\n", testsink->got_sample);
testsink->got_sample = 0; testsink->got_sample = 0;
ok(!testsink->got_begin_flush, "Got %u calls to IPin::BeginFlush().\n", testsink->got_begin_flush); ok(!testsink->got_begin_flush, "Got %u calls to IPin::BeginFlush().\n", testsink->got_begin_flush);
......
...@@ -1677,9 +1677,9 @@ static void test_seeking(void) ...@@ -1677,9 +1677,9 @@ static void test_seeking(void)
ok(ret, "Failed to delete file, error %lu.\n", GetLastError()); ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
} }
static void test_streaming(void) static void test_streaming(const WCHAR *resname)
{ {
const WCHAR *filename = load_resource(L"test.avi"); const WCHAR *filename = load_resource(resname);
IBaseFilter *filter = create_avi_splitter(); IBaseFilter *filter = create_avi_splitter();
IFilterGraph2 *graph = connect_input(filter, filename); IFilterGraph2 *graph = connect_input(filter, filename);
struct testfilter testsink; struct testfilter testsink;
...@@ -1691,6 +1691,8 @@ static void test_streaming(void) ...@@ -1691,6 +1691,8 @@ static void test_streaming(void)
ULONG ref; ULONG ref;
DWORD ret; DWORD ret;
winetest_push_context("File %ls", resname);
testfilter_init(&testsink); testfilter_init(&testsink);
IFilterGraph2_AddFilter(graph, &testsink.filter.IBaseFilter_iface, L"sink"); IFilterGraph2_AddFilter(graph, &testsink.filter.IBaseFilter_iface, L"sink");
IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control); IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
...@@ -1761,6 +1763,8 @@ static void test_streaming(void) ...@@ -1761,6 +1763,8 @@ static void test_streaming(void)
ok(!ref, "Got outstanding refcount %ld.\n", ref); ok(!ref, "Got outstanding refcount %ld.\n", ref);
ret = DeleteFileW(filename); ret = DeleteFileW(filename);
ok(ret, "Failed to delete file, error %lu.\n", GetLastError()); ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
winetest_pop_context();
} }
START_TEST(avisplit) START_TEST(avisplit)
...@@ -1787,7 +1791,8 @@ START_TEST(avisplit) ...@@ -1787,7 +1791,8 @@ START_TEST(avisplit)
test_unconnected_filter_state(); test_unconnected_filter_state();
test_connect_pin(); test_connect_pin();
test_seeking(); test_seeking();
test_streaming(); test_streaming(L"test.avi");
test_streaming(L"test_cinepak.avi");
CoUninitialize(); CoUninitialize();
} }
...@@ -39,3 +39,7 @@ test.wav RCDATA "test.wav" ...@@ -39,3 +39,7 @@ test.wav RCDATA "test.wav"
/* ffmpeg -f lavfi -i smptebars -f lavfi -i "sine=frequency=1000" -t 2.04 -r 25 -f mpeg -vcodec mpeg1video -vf scale=64x48 -acodec mp2 -ar 32k -ab 96k test2.mpg */ /* ffmpeg -f lavfi -i smptebars -f lavfi -i "sine=frequency=1000" -t 2.04 -r 25 -f mpeg -vcodec mpeg1video -vf scale=64x48 -acodec mp2 -ar 32k -ab 96k test2.mpg */
/* @makedep: test2.mpg */ /* @makedep: test2.mpg */
test2.mpg RCDATA "test2.mpg" test2.mpg RCDATA "test2.mpg"
/* ffmpeg -f lavfi -i smptebars -t 5 -r 1 -f avi -vcodec cinepak -pix_fmt rgb24 -vf scale=32x24 test_cinepak.avi */
/* @makedep: test_cinepak.avi */
test_cinepak.avi RCDATA "test_cinepak.avi"
File added