Commit 26146cdd authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

Started the real implementation of mciavi.

parent c6615832
......@@ -461,7 +461,7 @@ wininet/libwininet.@LIBEXT@: libshlwapi.@LIBEXT@ libuser32.@LIBEXT@ libkernel32.
winmm/joystick/libjoystick.drv.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libntdll.@LIBEXT@
winmm/libwinmm.@LIBEXT@: libuser32.@LIBEXT@ libadvapi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
winmm/mcianim/libmcianim.drv.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
winmm/mciavi/libmciavi.drv.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
winmm/mciavi/libmciavi.drv.@LIBEXT@: libmsvfw32.@LIBEXT@ libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libgdi32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
winmm/mcicda/libmcicda.drv.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
winmm/mciseq/libmciseq.drv.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
winmm/mciwave/libmciwave.drv.@LIBEXT@: libwinmm.@LIBEXT@ libuser32.@LIBEXT@ libkernel32.@LIBEXT@ libntdll.@LIBEXT@
......
......@@ -8,7 +8,13 @@ LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \
mciavi.c
info.c \
mciavi.c \
mmoutput.c \
wnd.c
RC_SRCS = \
mciavi_res.rc
@MAKE_DLL_RULES@
......
name mciavi
file mciavi.drv
type win32
init MCIAVI_LibMain
rsrc mciavi_res.res
import msvfw32.dll
import winmm.dll
import user32.dll
import gdi32.dll
import kernel32.dll
import ntdll.dll
import ntdll.dll
debug_channels (mciavi)
......
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*
* Digital video MCI Wine Driver
*
* Copyright 1999, 2000 Eric POUECH
*/
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "mmddk.h"
#include "digitalv.h"
#include "vfw.h"
#include "mciavi.h"
struct MMIOPos {
DWORD dwOffset;
DWORD dwSize;
};
typedef struct {
UINT wDevID;
int nUseCount; /* Incremented for each shared open */
BOOL16 fShareable; /* TRUE if first open was shareable */
HANDLE16 hCallback; /* Callback handle for pending notification */
WORD wCommandTable; /* custom MCI command table */
volatile DWORD dwStatus; /* One of MCI_MODE_XXX */
MCI_OPEN_PARMSA openParms;
DWORD dwMciTimeFormat; /* current time format */
DWORD dwSet; /* what's turned on: video & audio l&r */
/* information on the loaded AVI file */
HMMIO hFile; /* mmio file handle open as Element */
MainAVIHeader mah;
AVIStreamHeader ash_video;
AVIStreamHeader ash_audio;
LPBITMAPINFOHEADER inbih;
struct MMIOPos* lpVideoIndex;
LPWAVEFORMATEX lpWaveFormat;
struct MMIOPos* lpAudioIndex;
/* computed data from the file */
DWORD dwPlayableVideoFrames; /* max number of frames to be played. Takes care of truncated files and audio skew */
DWORD dwPlayableAudioBlocks;
/* data for the AVI decompressor */
HIC hic;
LPBITMAPINFOHEADER outbih;
LPVOID indata;
LPVOID outdata;
HBITMAP hbmFrame;
/* data for playing the audio part */
HANDLE hWave;
HANDLE hEvent; /* for synchronization */
DWORD dwEventCount; /* for synchronization */
/* data for play back */
HWND hWnd;
DWORD dwCurrVideoFrame; /* video frame to display and current position */
DWORD dwCurrAudioBlock; /* current audio block being played */
/* data for the background mechanism */
CRITICAL_SECTION cs;
} WINE_MCIAVI;
extern HINSTANCE MCIAVI_hInstance;
/* info.c */
DWORD MCIAVI_ConvertFrameToTimeFormat(WINE_MCIAVI* wma, DWORD val, LPDWORD lpRet);
DWORD MCIAVI_ConvertTimeFormatToFrame(WINE_MCIAVI* wma, DWORD val);
DWORD MCIAVI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms);
DWORD MCIAVI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_INFO_PARMSA lpParms);
DWORD MCIAVI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms);
DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpParms);
/* mmoutput.c */
BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma);
DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned* nHdr, LPWAVEHDR* pWaveHdr);
BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wma);
void MCIAVI_PlayAudioBlocks(WINE_MCIAVI* wma, unsigned nHdr, LPWAVEHDR waveHdr);
LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wma);
LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC);
/* mciavi.c */
WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID);
/* window.c */
BOOL MCIAVI_CreateWindow(WINE_MCIAVI* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpOpenParms);
DWORD MCIAVI_mciPut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PUT_PARMS lpParms);
DWORD MCIAVI_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms);
DWORD MCIAVI_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSA lpParms);
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*
* Digital video MCI Wine Driver
*
* Copyright 1999, 2000 Eric POUECH
*/
#include <string.h>
#include "private_mciavi.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(mciavi);
static LRESULT WINAPI MCIAVI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hWnd, uMsg, wParam, lParam);
if (!(WINE_MCIAVI*)GetWindowLongA(hWnd, 0) && uMsg != WM_CREATE)
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
switch (uMsg) {
case WM_CREATE:
SetWindowLongA(hWnd, 0, (LPARAM)((CREATESTRUCTA*)lParam)->lpCreateParams);
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
case WM_DESTROY:
SetWindowLongA(hWnd, 0, 0);
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
case WM_ERASEBKGND:
{
RECT rect;
GetClientRect(hWnd, &rect);
FillRect((HDC)wParam, &rect, GetStockObject(BLACK_BRUSH));
}
break;
case WM_PAINT:
{
WINE_MCIAVI* wma = (WINE_MCIAVI*)GetWindowLongA(hWnd, 0);
/* the animation isn't playing, don't paint */
if (wma->dwStatus == MCI_MODE_NOT_READY)
/* default paint handling */
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
if (wParam) {
EnterCriticalSection(&wma->cs);
MCIAVI_PaintFrame(wma, (HDC)wParam);
LeaveCriticalSection(&wma->cs);
} else {
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
EnterCriticalSection(&wma->cs);
MCIAVI_PaintFrame(wma, hDC);
LeaveCriticalSection(&wma->cs);
EndPaint(hWnd, &ps);
}
}
break;
default:
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
}
return 0;
}
BOOL MCIAVI_CreateWindow(WINE_MCIAVI* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpOpenParms)
{
WNDCLASSA wndClass;
HWND hParent = 0;
DWORD dwStyle = WS_OVERLAPPEDWINDOW;
int p = CW_USEDEFAULT;
/* what should be done ? */
if (wma->hWnd) return TRUE;
ZeroMemory(&wndClass, sizeof(WNDCLASSA));
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
wndClass.lpfnWndProc = (WNDPROC)MCIAVI_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(WINE_MCIAVI*);
wndClass.hCursor = LoadCursorA(0, IDC_ARROWA);
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndClass.lpszClassName = "MCIAVI";
RegisterClassA(&wndClass);
if (dwFlags & MCI_DGV_OPEN_PARENT) hParent = lpOpenParms->hWndParent;
if (dwFlags & MCI_DGV_OPEN_WS) dwStyle = lpOpenParms->dwStyle;
if (dwStyle & WS_CHILD) p = 0;
wma->hWnd = CreateWindowA("MCIAVI", "Wine MCI-AVI player",
dwStyle, p, p,
(wma->hic ? wma->outbih : wma->inbih)->biWidth,
(wma->hic ? wma->outbih : wma->inbih)->biHeight,
hParent, 0, MCIAVI_hInstance, wma);
return (BOOL)wma->hWnd;
}
/***************************************************************************
* MCIAVI_mciPut [internal]
*/
DWORD MCIAVI_mciPut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PUT_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
RECT rc;
char buffer[256];
FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
if (dwFlags & MCI_DGV_RECT) {
rc = lpParms->rc;
} else {
SetRectEmpty(&rc);
}
*buffer = 0;
if (dwFlags & MCI_DGV_PUT_CLIENT) {
strncat(buffer, "PUT_CLIENT", sizeof(buffer));
}
if (dwFlags & MCI_DGV_PUT_DESTINATION) {
strncat(buffer, "PUT_DESTINATION", sizeof(buffer));
}
if (dwFlags & MCI_DGV_PUT_FRAME) {
strncat(buffer, "PUT_FRAME", sizeof(buffer));
}
if (dwFlags & MCI_DGV_PUT_SOURCE) {
strncat(buffer, "PUT_SOURCE", sizeof(buffer));
}
if (dwFlags & MCI_DGV_PUT_VIDEO) {
strncat(buffer, "PUT_VIDEO", sizeof(buffer));
}
if (dwFlags & MCI_DGV_PUT_WINDOW) {
strncat(buffer, "PUT_WINDOW", sizeof(buffer));
}
TRACE("%s (%d,%d,%d,%d)\n", buffer, rc.left, rc.top, rc.right, rc.bottom);
return 0;
}
/******************************************************************************
* MCIAVI_mciWhere [internal]
*/
DWORD MCIAVI_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
LPSTR x = "";
TRACE("(%04x, %08lx, %p)\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
if (dwFlags & MCI_DGV_WHERE_MAX) FIXME("Max NIY\n");
if (dwFlags & MCI_DGV_WHERE_DESTINATION) {
x = "Dest";
GetClientRect(wma->hWnd, &lpParms->rc);
}
if (dwFlags & MCI_DGV_WHERE_FRAME) {
FIXME(x = "Frame");
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_WHERE_SOURCE) {
x = "Source";
lpParms->rc.left = lpParms->rc.top = 0;
lpParms->rc.right = wma->mah.dwWidth;
lpParms->rc.bottom = wma->mah.dwHeight;
}
if (dwFlags & MCI_DGV_WHERE_VIDEO) {
FIXME(x = "Video");
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_WHERE_WINDOW) {
x = "Window";
GetClientRect(wma->hWnd, &lpParms->rc);
}
TRACE("%s -> (%d,%d,%d,%d)\n",
x, lpParms->rc.left, lpParms->rc.top, lpParms->rc.right, lpParms->rc.bottom);
return 0;
}
/***************************************************************************
* MCIAVI_mciWindow [internal]
*/
DWORD MCIAVI_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
if (dwFlags & MCI_DGV_WINDOW_HWND) {
FIXME("Setting hWnd to %08lx\n", (DWORD)lpParms->hWnd);
#if 0
if (wma->hWnd) DestroyWindow(wma->hWnd);
/* is the window to be subclassed ? */
wma->hWnd = lpParms->hWnd;
#endif
}
if (dwFlags & MCI_DGV_WINDOW_STATE) {
TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow);
ShowWindow(wma->hWnd, lpParms->nCmdShow);
}
if (dwFlags & MCI_DGV_WINDOW_TEXT) {
TRACE("Setting caption to '%s'\n", lpParms->lpstrText);
SetWindowTextA(wma->hWnd, lpParms->lpstrText);
}
return 0;
}
......@@ -36,6 +36,7 @@ INSTALLED_INCLUDES = \
lzexpand.h \
mapi.h \
mapidefs.h \
mciavi.h \
mcx.h \
mmreg.h \
mmsystem.h \
......
#define MCI_MCIAVI_PLAY_WINDOW 0x01000000L
#define MCI_MCIAVI_PLAY_FULLSCREEN 0x02000000L
#define MCI_MCIAVI_PLAY_FULLBY2 0x04000000L
#define MCI_AVI_STATUS_FRAMES_SKIPPED 0x8001L
#define MCI_AVI_STATUS_LAST_PLAY_SPEED 0x8002L
#define MCI_AVI_STATUS_AUDIO_BREAKS 0x8003L
#define MCI_AVI_SETVIDEO_DRAW_PROCEDURE 0x8000L
#define MCI_AVI_SETVIDEO_PALETTE_COLOR 0x8100L
#define MCI_AVI_SETVIDEO_PALETTE_HALFTONE 0x0000FFFFL
#define MCIERR_AVI_OLDAVIFORMAT (MCIERR_CUSTOM_DRIVER_BASE + 100)
#define MCIERR_AVI_NOTINTERLEAVED (MCIERR_CUSTOM_DRIVER_BASE + 101)
#define MCIERR_AVI_NODISPDIB (MCIERR_CUSTOM_DRIVER_BASE + 102)
#define MCIERR_AVI_CANTPLAYFULLSCREEN (MCIERR_CUSTOM_DRIVER_BASE + 103)
#define MCIERR_AVI_TOOBIGFORVGA (MCIERR_CUSTOM_DRIVER_BASE + 104)
#define MCIERR_AVI_NOCOMPRESSOR (MCIERR_CUSTOM_DRIVER_BASE + 105)
#define MCIERR_AVI_DISPLAYERROR (MCIERR_CUSTOM_DRIVER_BASE + 106)
#define MCIERR_AVI_AUDIOERROR (MCIERR_CUSTOM_DRIVER_BASE + 107)
#define MCIERR_AVI_BADPALETTE (MCIERR_CUSTOM_DRIVER_BASE + 108)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment