1 |
/* |
2 |
* VCM.cs |
3 |
* Copyright (c) 2007-2009 kbinani |
4 |
* |
5 |
* This file is part of Boare.Lib.Media. |
6 |
* |
7 |
* Boare.Lib.Media is free software; you can redistribute it and/or |
8 |
* modify it under the terms of the BSD License. |
9 |
* |
10 |
* Boare.Lib.Media is distributed in the hope that it will be useful, |
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
13 |
*/ |
14 |
using System; |
15 |
using System.Collections.Generic; |
16 |
using System.Text; |
17 |
using System.Runtime.InteropServices; |
18 |
using System.IO; |
19 |
|
20 |
using bocoree; |
21 |
|
22 |
namespace Boare.Lib.Media { |
23 |
|
24 |
public class VCM { |
25 |
public const uint ICMODE_QUERY = 4; |
26 |
public const uint ICMF_CHOOSE_ALLCOMPRESSORS = 0x08; |
27 |
public static readonly uint ICTYPE_VIDEO = Util.mmioFOURCC( 'v', 'i', 'd', 'c' ); |
28 |
public static readonly uint ICTYPE_AUDIO = Util.mmioFOURCC( 'a', 'u', 'd', 'c' ); |
29 |
public const uint ICM_COMPRESS_GET_FORMAT = 0x4004; |
30 |
|
31 |
[DllImport( "msvfw32.dll" )] |
32 |
public static extern UInt32 ICOpen( UInt32 fccType, UInt32 fccHandler, uint wMode ); |
33 |
|
34 |
[DllImport( "msvfw32.dll" )] |
35 |
public static unsafe extern int ICGetInfo( UInt32 hic, ICINFO* icinfo, int size ); |
36 |
/*unsafe public static int ICGetInfo( UInt32 hic, ref ICINFO icinfo, int size ) { |
37 |
IntPtr pt = new IntPtr( 0 ); |
38 |
int r = w_ICGetInfo( hic, &pt, size ); |
39 |
ICINFO result = new ICINFO(); |
40 |
result = (ICINFO)Marshal.PtrToStructure( pt, result.GetType() ); |
41 |
icinfo = result; |
42 |
return r; |
43 |
}*/ |
44 |
|
45 |
[DllImport( "msvfw32.dll" )] |
46 |
public static extern int ICClose( UInt32 hic ); |
47 |
|
48 |
[DllImport( "msvfw32.dll" )] |
49 |
public static unsafe extern int ICCompressorChoose( |
50 |
IntPtr hwnd, |
51 |
UInt32 uiFlags, |
52 |
IntPtr pvIn, |
53 |
IntPtr lpData, |
54 |
COMPVARS* pc, |
55 |
string lpszTitle |
56 |
); |
57 |
|
58 |
[DllImport( "msvfw32.dll" )] |
59 |
public static unsafe extern int ICSeqCompressFrameStart( |
60 |
COMPVARS* pc, |
61 |
BITMAPINFO* lpbiIn |
62 |
); |
63 |
|
64 |
[DllImport( "msvfw32.dll" )] |
65 |
public static unsafe extern void ICSeqCompressFrameEnd( COMPVARS* pc ); |
66 |
|
67 |
[DllImport( "msvfw32.dll" )] |
68 |
public static unsafe extern void ICCompressorFree( COMPVARS* pc ); |
69 |
|
70 |
[DllImport( "msvfw32.dll" )] |
71 |
public static unsafe extern IntPtr ICSeqCompressFrame( |
72 |
COMPVARS* pc, |
73 |
UInt32 uiFlags, |
74 |
IntPtr lpBits, |
75 |
Int32* pfKey, |
76 |
Int32* plSize |
77 |
); |
78 |
|
79 |
[DllImport( "msvfw32.dll" )] |
80 |
public static unsafe extern UIntPtr ICSendMessage( UInt32 hic, UInt32 wMsg, IntPtr dw1, IntPtr dw2 ); |
81 |
|
82 |
public static unsafe uint ICCompressGetFormatSize( UInt32 hic, BITMAPINFO* lpbi ) { |
83 |
return ICCompressGetFormat( hic, lpbi, (BITMAPINFO*)0 ); |
84 |
} |
85 |
|
86 |
|
87 |
public static unsafe uint ICCompressGetFormat( UInt32 hic, BITMAPINFO* lpbiInput, BITMAPINFO* lpbiOutput ) { |
88 |
return (uint)ICSendMessage( hic, ICM_COMPRESS_GET_FORMAT, (IntPtr)lpbiInput, (IntPtr)lpbiOutput ); |
89 |
} |
90 |
} |
91 |
|
92 |
|
93 |
[StructLayout( LayoutKind.Sequential, Pack = 1 )] |
94 |
public struct ICINFO { |
95 |
public UInt32 dwSize; |
96 |
public UInt32 fccType; |
97 |
public UInt32 fccHandler; |
98 |
public UInt32 dwFlags; |
99 |
public UInt32 dwVersion; |
100 |
public UInt32 dwVersionICM; |
101 |
private sz16 szName; |
102 |
private sz128 szDescription; |
103 |
private sz128 szDriver; |
104 |
public string Name { |
105 |
get { |
106 |
string t = szName.Value; |
107 |
//return t.ToCharArray(); |
108 |
return t; |
109 |
} |
110 |
} |
111 |
public string Description { |
112 |
get { |
113 |
string t = szDescription.Value; |
114 |
//return t.ToCharArray(); |
115 |
return t; |
116 |
} |
117 |
} |
118 |
public string Driver { |
119 |
get { |
120 |
string t = szDriver.Value; |
121 |
//return t.ToCharArray(); |
122 |
return t; |
123 |
} |
124 |
} |
125 |
[StructLayout( LayoutKind.Sequential, Pack = 1 )] |
126 |
private struct sz4 { |
127 |
UInt16 UInt16_1; |
128 |
UInt16 UInt16_2; |
129 |
UInt16 UInt16_3; |
130 |
UInt16 UInt16_4; |
131 |
public string Value { |
132 |
get { |
133 |
return "" + (char)UInt16_1 + (char)UInt16_2 + (char)UInt16_3 + (char)UInt16_4; |
134 |
} |
135 |
} |
136 |
} |
137 |
[StructLayout( LayoutKind.Sequential, Pack = 1 )] |
138 |
private struct sz16 { |
139 |
sz4 sz4_1; |
140 |
sz4 sz4_2; |
141 |
sz4 sz4_3; |
142 |
sz4 sz4_4; |
143 |
public string Value { |
144 |
get { |
145 |
return sz4_1.Value + sz4_2.Value + sz4_3.Value + sz4_4.Value; |
146 |
} |
147 |
} |
148 |
} |
149 |
[StructLayout( LayoutKind.Sequential, Pack = 1 )] |
150 |
private struct sz64 { |
151 |
sz16 sz16_1; |
152 |
sz16 sz16_2; |
153 |
sz16 sz16_3; |
154 |
sz16 sz16_4; |
155 |
public string Value { |
156 |
get { |
157 |
return sz16_1.Value + sz16_2.Value + sz16_3.Value + sz16_4.Value; |
158 |
} |
159 |
} |
160 |
} |
161 |
[StructLayout( LayoutKind.Sequential, Pack = 1 )] |
162 |
private struct sz128 { |
163 |
sz64 sz64_1; |
164 |
sz64 sz64_2; |
165 |
public string Value { |
166 |
get { |
167 |
return sz64_1.Value + sz64_2.Value; |
168 |
} |
169 |
} |
170 |
} |
171 |
} |
172 |
|
173 |
|
174 |
[StructLayout( LayoutKind.Sequential, Pack = 1 )] |
175 |
public unsafe struct COMPVARS { |
176 |
public Int32 cbSize; |
177 |
public UInt32 dwFlags; |
178 |
public UInt32 hic; // 元はHIC |
179 |
public UInt32 fccType; |
180 |
public UInt32 fccHandler; |
181 |
public BITMAPINFOHEADER* lpbiIn; |
182 |
public BITMAPINFOHEADER* lpbiOut; |
183 |
public void* lpBitsOut; |
184 |
public void* lpBitsPrev; |
185 |
public Int32 lFrame; |
186 |
public Int32 lKey; |
187 |
public Int32 lDataRate; |
188 |
public Int32 lQ; |
189 |
public Int32 lKeyCount; |
190 |
public void* lpState; |
191 |
public Int32 cbState; |
192 |
public override string ToString() { |
193 |
return "{cbSize=" + cbSize + |
194 |
",dwFlags=" + dwFlags + |
195 |
",hic=" + hic + |
196 |
",fccType=" + fccType + |
197 |
",fccHandler=" + fccHandler + |
198 |
",lpbiIn=" + ((int)lpbiIn).ToString() + |
199 |
",lpbiOut=" + ((int)lpbiOut).ToString() + |
200 |
",lpBitsOut=" + ((int)lpBitsOut).ToString() + |
201 |
",lpBitsPrev=" + ((int)lpBitsPrev).ToString() + |
202 |
",lFrame=" + lFrame + |
203 |
",lKey=" + lKey + |
204 |
",lDataRate=" + lDataRate + |
205 |
",lQ=" + lQ + |
206 |
",lKeyCount=" + lKeyCount + |
207 |
",lpState=" + ((int)lpState).ToString() + |
208 |
",cbState=" + cbState + "}"; |
209 |
} |
210 |
} |
211 |
|
212 |
[StructLayout(LayoutKind.Sequential, Pack=1)] |
213 |
public struct BITMAPINFO { |
214 |
public BITMAPINFOHEADER bmiHeader; |
215 |
public RGBQUAD bmiColors; |
216 |
public unsafe void Write( BinaryWriter bw ) { |
217 |
bmiHeader.Write( bw ); |
218 |
int remain = (int)((bmiHeader.biSize - sizeof( BITMAPINFOHEADER )) / sizeof( RGBQUAD )); |
219 |
fixed ( RGBQUAD* rgbq = &bmiColors ) { // これ以外に,「落ちないやり方」が無かった.メモリーが連続していることを祈るのみ |
220 |
for ( int i = 0; i < remain; i++ ) { |
221 |
bw.Write( rgbq[i].rgbBlue ); |
222 |
bw.Write( rgbq[i].rgbGreen ); |
223 |
bw.Write( rgbq[i].rgbRed ); |
224 |
bw.Write( rgbq[i].rgbReserved ); |
225 |
} |
226 |
} |
227 |
} |
228 |
} |
229 |
|
230 |
[StructLayout(LayoutKind.Sequential, Pack = 1)] |
231 |
public struct RGBQUAD { |
232 |
public byte rgbBlue; |
233 |
public byte rgbGreen; |
234 |
public byte rgbRed; |
235 |
public byte rgbReserved; |
236 |
} |
237 |
|
238 |
} |