5 #include "../../Windows/Defs.h"
\r
6 #include "../../Windows/PropVariant.h"
\r
8 #include "CreateCoder.h"
\r
10 #include "FilterCoder.h"
\r
11 #include "RegisterCodec.h"
\r
13 static const unsigned int kNumCodecsMax = 64;
\r
14 unsigned int g_NumCodecs = 0;
\r
15 const CCodecInfo *g_Codecs[kNumCodecsMax];
\r
16 void RegisterCodec(const CCodecInfo *codecInfo)
\r
18 if (g_NumCodecs < kNumCodecsMax)
\r
19 g_Codecs[g_NumCodecs++] = codecInfo;
\r
22 #ifdef EXTERNAL_CODECS
\r
23 static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)
\r
25 NWindows::NCOM::CPropVariant prop;
\r
26 RINOK(codecsInfo->GetProperty(index, propID, &prop));
\r
27 if (prop.vt == VT_EMPTY)
\r
29 else if (prop.vt == VT_UI4)
\r
32 return E_INVALIDARG;
\r
36 static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res)
\r
38 NWindows::NCOM::CPropVariant prop;
\r
39 RINOK(codecsInfo->GetProperty(index, propID, &prop));
\r
40 if (prop.vt == VT_EMPTY)
\r
42 else if (prop.vt == VT_BOOL)
\r
43 res = VARIANT_BOOLToBool(prop.boolVal);
\r
45 return E_INVALIDARG;
\r
49 HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)
\r
52 RINOK(codecsInfo->GetNumberOfMethods(&num));
\r
53 for (UInt32 i = 0; i < num; i++)
\r
56 NWindows::NCOM::CPropVariant prop;
\r
57 RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));
\r
58 // if (prop.vt != VT_BSTR)
\r
59 // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
\r
60 // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);
\r
61 if (prop.vt != VT_UI8)
\r
63 continue; // old Interface
\r
64 // return E_INVALIDARG;
\r
66 info.Id = prop.uhVal.QuadPart;
\r
69 RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));
\r
70 if (prop.vt == VT_BSTR)
\r
71 info.Name = prop.bstrVal;
\r
72 else if (prop.vt != VT_EMPTY)
\r
73 return E_INVALIDARG;;
\r
75 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));
\r
76 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));
\r
77 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
\r
78 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
\r
80 externalCodecs.Add(info);
\r
88 #ifdef EXTERNAL_CODECS
\r
89 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
\r
91 const UString &name,
\r
92 CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
\r
95 for (i = 0; i < g_NumCodecs; i++)
\r
97 const CCodecInfo &codec = *g_Codecs[i];
\r
98 if (name.CompareNoCase(codec.Name) == 0)
\r
100 methodId = codec.Id;
\r
101 numInStreams = codec.NumInStreams;
\r
106 #ifdef EXTERNAL_CODECS
\r
107 if (externalCodecs)
\r
108 for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
\r
110 const CCodecInfoEx &codec = (*externalCodecs)[i];
\r
111 if (codec.Name.CompareNoCase(name) == 0)
\r
113 methodId = codec.Id;
\r
114 numInStreams = codec.NumInStreams;
\r
115 numOutStreams = codec.NumOutStreams;
\r
124 #ifdef EXTERNAL_CODECS
\r
125 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
\r
127 CMethodId methodId, UString &name)
\r
130 for (i = 0; i < g_NumCodecs; i++)
\r
132 const CCodecInfo &codec = *g_Codecs[i];
\r
133 if (methodId == codec.Id)
\r
139 #ifdef EXTERNAL_CODECS
\r
140 if (externalCodecs)
\r
141 for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
\r
143 const CCodecInfoEx &codec = (*externalCodecs)[i];
\r
144 if (methodId == codec.Id)
\r
154 HRESULT CreateCoder(
\r
155 DECL_EXTERNAL_CODECS_LOC_VARS
\r
156 CMethodId methodId,
\r
157 CMyComPtr<ICompressFilter> &filter,
\r
158 CMyComPtr<ICompressCoder> &coder,
\r
159 CMyComPtr<ICompressCoder2> &coder2,
\r
160 bool encode, bool onlyCoder)
\r
162 bool created = false;
\r
164 for (i = 0; i < g_NumCodecs; i++)
\r
166 const CCodecInfo &codec = *g_Codecs[i];
\r
167 if (codec.Id == methodId)
\r
171 if (codec.CreateEncoder)
\r
173 void *p = codec.CreateEncoder();
\r
174 if (codec.IsFilter) filter = (ICompressFilter *)p;
\r
175 else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
\r
176 else coder2 = (ICompressCoder2 *)p;
\r
177 created = (p != 0);
\r
182 if (codec.CreateDecoder)
\r
184 void *p = codec.CreateDecoder();
\r
185 if (codec.IsFilter) filter = (ICompressFilter *)p;
\r
186 else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
\r
187 else coder2 = (ICompressCoder2 *)p;
\r
188 created = (p != 0);
\r
194 #ifdef EXTERNAL_CODECS
\r
195 if (!created && externalCodecs)
\r
196 for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
\r
198 const CCodecInfoEx &codec = (*externalCodecs)[i];
\r
199 if (codec.Id == methodId)
\r
203 if (codec.EncoderIsAssigned)
\r
205 if (codec.IsSimpleCodec())
\r
207 HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
\r
208 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
\r
212 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
\r
217 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
\r
223 if (codec.DecoderIsAssigned)
\r
225 if (codec.IsSimpleCodec())
\r
227 HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
\r
228 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
\r
232 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
\r
237 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
\r
245 if (onlyCoder && filter)
\r
247 CFilterCoder *coderSpec = new CFilterCoder;
\r
249 coderSpec->Filter = filter;
\r
254 HRESULT CreateCoder(
\r
255 DECL_EXTERNAL_CODECS_LOC_VARS
\r
256 CMethodId methodId,
\r
257 CMyComPtr<ICompressCoder> &coder,
\r
258 CMyComPtr<ICompressCoder2> &coder2,
\r
261 CMyComPtr<ICompressFilter> filter;
\r
262 return CreateCoder(
\r
263 EXTERNAL_CODECS_LOC_VARS
\r
265 filter, coder, coder2, encode, true);
\r
268 HRESULT CreateCoder(
\r
269 DECL_EXTERNAL_CODECS_LOC_VARS
\r
270 CMethodId methodId,
\r
271 CMyComPtr<ICompressCoder> &coder, bool encode)
\r
273 CMyComPtr<ICompressFilter> filter;
\r
274 CMyComPtr<ICompressCoder2> coder2;
\r
275 return CreateCoder(
\r
276 EXTERNAL_CODECS_LOC_VARS
\r
278 coder, coder2, encode);
\r
281 HRESULT CreateFilter(
\r
282 DECL_EXTERNAL_CODECS_LOC_VARS
\r
283 CMethodId methodId,
\r
284 CMyComPtr<ICompressFilter> &filter,
\r
287 CMyComPtr<ICompressCoder> coder;
\r
288 CMyComPtr<ICompressCoder2> coder2;
\r
289 return CreateCoder(
\r
290 EXTERNAL_CODECS_LOC_VARS
\r
292 filter, coder, coder2, encode, false);
\r