5 #include "CreateCoder.h"
7 #include "../../Windows/PropVariant.h"
8 #include "../../Windows/Defs.h"
9 #include "FilterCoder.h"
10 #include "RegisterCodec.h"
12 static const unsigned int kNumCodecsMax = 64;
13 unsigned int g_NumCodecs = 0;
14 const CCodecInfo *g_Codecs[kNumCodecsMax];
15 void RegisterCodec(const CCodecInfo *codecInfo)
17 if (g_NumCodecs < kNumCodecsMax)
18 g_Codecs[g_NumCodecs++] = codecInfo;
21 #ifdef EXTERNAL_CODECS
22 static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)
24 NWindows::NCOM::CPropVariant prop;
25 RINOK(codecsInfo->GetProperty(index, propID, &prop));
26 if (prop.vt == VT_EMPTY)
28 else if (prop.vt == VT_UI4)
35 static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res)
37 NWindows::NCOM::CPropVariant prop;
38 RINOK(codecsInfo->GetProperty(index, propID, &prop));
39 if (prop.vt == VT_EMPTY)
41 else if (prop.vt == VT_BOOL)
42 res = VARIANT_BOOLToBool(prop.boolVal);
48 HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)
51 RINOK(codecsInfo->GetNumberOfMethods(&num));
52 for (UInt32 i = 0; i < num; i++)
55 NWindows::NCOM::CPropVariant prop;
56 RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));
57 // if (prop.vt != VT_BSTR)
58 // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
59 // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);
60 if (prop.vt != VT_UI8)
62 continue; // old Interface
63 // return E_INVALIDARG;
65 info.Id = prop.uhVal.QuadPart;
68 RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));
69 if (prop.vt == VT_BSTR)
70 info.Name = prop.bstrVal;
71 else if (prop.vt != VT_EMPTY)
74 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));
75 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));
76 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
77 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
79 externalCodecs.Add(info);
87 #ifdef EXTERNAL_CODECS
88 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
91 CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
94 for (i = 0; i < g_NumCodecs; i++)
96 const CCodecInfo &codec = *g_Codecs[i];
97 if (name.CompareNoCase(codec.Name) == 0)
100 numInStreams = codec.NumInStreams;
105 #ifdef EXTERNAL_CODECS
107 for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
109 const CCodecInfoEx &codec = (*externalCodecs)[i];
110 if (codec.Name.CompareNoCase(name) == 0)
113 numInStreams = codec.NumInStreams;
114 numOutStreams = codec.NumOutStreams;
123 #ifdef EXTERNAL_CODECS
124 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
126 CMethodId methodId, UString &name)
129 for (i = 0; i < g_NumCodecs; i++)
131 const CCodecInfo &codec = *g_Codecs[i];
132 if (methodId == codec.Id)
138 #ifdef EXTERNAL_CODECS
140 for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
142 const CCodecInfoEx &codec = (*externalCodecs)[i];
143 if (methodId == codec.Id)
154 DECL_EXTERNAL_CODECS_LOC_VARS
156 CMyComPtr<ICompressFilter> &filter,
157 CMyComPtr<ICompressCoder> &coder,
158 CMyComPtr<ICompressCoder2> &coder2,
159 bool encode, bool onlyCoder)
161 bool created = false;
163 for (i = 0; i < g_NumCodecs; i++)
165 const CCodecInfo &codec = *g_Codecs[i];
166 if (codec.Id == methodId)
170 if (codec.CreateEncoder)
172 void *p = codec.CreateEncoder();
173 if (codec.IsFilter) filter = (ICompressFilter *)p;
174 else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
175 else coder2 = (ICompressCoder2 *)p;
181 if (codec.CreateDecoder)
183 void *p = codec.CreateDecoder();
184 if (codec.IsFilter) filter = (ICompressFilter *)p;
185 else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
186 else coder2 = (ICompressCoder2 *)p;
193 #ifdef EXTERNAL_CODECS
194 if (!created && externalCodecs)
195 for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
197 const CCodecInfoEx &codec = (*externalCodecs)[i];
198 if (codec.Id == methodId)
202 if (codec.EncoderIsAssigned)
204 if (codec.IsSimpleCodec())
206 HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
207 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
211 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
216 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
222 if (codec.DecoderIsAssigned)
224 if (codec.IsSimpleCodec())
226 HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
227 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE)
231 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
236 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
244 if (onlyCoder && filter)
246 CFilterCoder *coderSpec = new CFilterCoder;
248 coderSpec->Filter = filter;
254 DECL_EXTERNAL_CODECS_LOC_VARS
256 CMyComPtr<ICompressCoder> &coder,
257 CMyComPtr<ICompressCoder2> &coder2,
260 CMyComPtr<ICompressFilter> filter;
262 EXTERNAL_CODECS_LOC_VARS
264 filter, coder, coder2, encode, true);
268 DECL_EXTERNAL_CODECS_LOC_VARS
270 CMyComPtr<ICompressCoder> &coder, bool encode)
272 CMyComPtr<ICompressFilter> filter;
273 CMyComPtr<ICompressCoder2> coder2;
275 EXTERNAL_CODECS_LOC_VARS
277 coder, coder2, encode);
280 HRESULT CreateFilter(
281 DECL_EXTERNAL_CODECS_LOC_VARS
283 CMyComPtr<ICompressFilter> &filter,
286 CMyComPtr<ICompressCoder> coder;
287 CMyComPtr<ICompressCoder2> coder2;
289 EXTERNAL_CODECS_LOC_VARS
291 filter, coder, coder2, encode, false);