| OLD | NEW |
| (Empty) |
| 1 // CreateCoder.cpp | |
| 2 | |
| 3 #include "StdAfx.h" | |
| 4 | |
| 5 #include "CreateCoder.h" | |
| 6 | |
| 7 #include "../../Windows/PropVariant.h" | |
| 8 #include "../../Windows/Defs.h" | |
| 9 #include "FilterCoder.h" | |
| 10 #include "RegisterCodec.h" | |
| 11 | |
| 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) | |
| 16 { | |
| 17 if (g_NumCodecs < kNumCodecsMax) | |
| 18 g_Codecs[g_NumCodecs++] = codecInfo; | |
| 19 } | |
| 20 | |
| 21 #ifdef EXTERNAL_CODECS | |
| 22 static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index
, PROPID propID, UInt32 &res) | |
| 23 { | |
| 24 NWindows::NCOM::CPropVariant prop; | |
| 25 RINOK(codecsInfo->GetProperty(index, propID, &prop)); | |
| 26 if (prop.vt == VT_EMPTY) | |
| 27 res = 1; | |
| 28 else if (prop.vt == VT_UI4) | |
| 29 res = prop.ulVal; | |
| 30 else | |
| 31 return E_INVALIDARG; | |
| 32 return S_OK; | |
| 33 } | |
| 34 | |
| 35 static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index,
PROPID propID, bool &res) | |
| 36 { | |
| 37 NWindows::NCOM::CPropVariant prop; | |
| 38 RINOK(codecsInfo->GetProperty(index, propID, &prop)); | |
| 39 if (prop.vt == VT_EMPTY) | |
| 40 res = true; | |
| 41 else if (prop.vt == VT_BOOL) | |
| 42 res = VARIANT_BOOLToBool(prop.boolVal); | |
| 43 else | |
| 44 return E_INVALIDARG; | |
| 45 return S_OK; | |
| 46 } | |
| 47 | |
| 48 HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodec
InfoEx> &externalCodecs) | |
| 49 { | |
| 50 UInt32 num; | |
| 51 RINOK(codecsInfo->GetNumberOfMethods(&num)); | |
| 52 for (UInt32 i = 0; i < num; i++) | |
| 53 { | |
| 54 CCodecInfoEx info; | |
| 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) | |
| 61 { | |
| 62 continue; // old Interface | |
| 63 // return E_INVALIDARG; | |
| 64 } | |
| 65 info.Id = prop.uhVal.QuadPart; | |
| 66 prop.Clear(); | |
| 67 | |
| 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) | |
| 72 return E_INVALIDARG;; | |
| 73 | |
| 74 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.Num
InStreams)); | |
| 75 RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.Nu
mOutStreams)); | |
| 76 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, i
nfo.EncoderIsAssigned)); | |
| 77 RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, i
nfo.DecoderIsAssigned)); | |
| 78 | |
| 79 externalCodecs.Add(info); | |
| 80 } | |
| 81 return S_OK; | |
| 82 } | |
| 83 | |
| 84 #endif | |
| 85 | |
| 86 bool FindMethod( | |
| 87 #ifdef EXTERNAL_CODECS | |
| 88 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *ext
ernalCodecs, | |
| 89 #endif | |
| 90 const UString &name, | |
| 91 CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams) | |
| 92 { | |
| 93 UInt32 i; | |
| 94 for (i = 0; i < g_NumCodecs; i++) | |
| 95 { | |
| 96 const CCodecInfo &codec = *g_Codecs[i]; | |
| 97 if (name.CompareNoCase(codec.Name) == 0) | |
| 98 { | |
| 99 methodId = codec.Id; | |
| 100 numInStreams = codec.NumInStreams; | |
| 101 numOutStreams = 1; | |
| 102 return true; | |
| 103 } | |
| 104 } | |
| 105 #ifdef EXTERNAL_CODECS | |
| 106 if (externalCodecs) | |
| 107 for (i = 0; i < (UInt32)externalCodecs->Size(); i++) | |
| 108 { | |
| 109 const CCodecInfoEx &codec = (*externalCodecs)[i]; | |
| 110 if (codec.Name.CompareNoCase(name) == 0) | |
| 111 { | |
| 112 methodId = codec.Id; | |
| 113 numInStreams = codec.NumInStreams; | |
| 114 numOutStreams = codec.NumOutStreams; | |
| 115 return true; | |
| 116 } | |
| 117 } | |
| 118 #endif | |
| 119 return false; | |
| 120 } | |
| 121 | |
| 122 bool FindMethod( | |
| 123 #ifdef EXTERNAL_CODECS | |
| 124 ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *ext
ernalCodecs, | |
| 125 #endif | |
| 126 CMethodId methodId, UString &name) | |
| 127 { | |
| 128 UInt32 i; | |
| 129 for (i = 0; i < g_NumCodecs; i++) | |
| 130 { | |
| 131 const CCodecInfo &codec = *g_Codecs[i]; | |
| 132 if (methodId == codec.Id) | |
| 133 { | |
| 134 name = codec.Name; | |
| 135 return true; | |
| 136 } | |
| 137 } | |
| 138 #ifdef EXTERNAL_CODECS | |
| 139 if (externalCodecs) | |
| 140 for (i = 0; i < (UInt32)externalCodecs->Size(); i++) | |
| 141 { | |
| 142 const CCodecInfoEx &codec = (*externalCodecs)[i]; | |
| 143 if (methodId == codec.Id) | |
| 144 { | |
| 145 name = codec.Name; | |
| 146 return true; | |
| 147 } | |
| 148 } | |
| 149 #endif | |
| 150 return false; | |
| 151 } | |
| 152 | |
| 153 HRESULT CreateCoder( | |
| 154 DECL_EXTERNAL_CODECS_LOC_VARS | |
| 155 CMethodId methodId, | |
| 156 CMyComPtr<ICompressFilter> &filter, | |
| 157 CMyComPtr<ICompressCoder> &coder, | |
| 158 CMyComPtr<ICompressCoder2> &coder2, | |
| 159 bool encode, bool onlyCoder) | |
| 160 { | |
| 161 bool created = false; | |
| 162 UInt32 i; | |
| 163 for (i = 0; i < g_NumCodecs; i++) | |
| 164 { | |
| 165 const CCodecInfo &codec = *g_Codecs[i]; | |
| 166 if (codec.Id == methodId) | |
| 167 { | |
| 168 if (encode) | |
| 169 { | |
| 170 if (codec.CreateEncoder) | |
| 171 { | |
| 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; | |
| 176 created = (p != 0); | |
| 177 break; | |
| 178 } | |
| 179 } | |
| 180 else | |
| 181 if (codec.CreateDecoder) | |
| 182 { | |
| 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; | |
| 187 created = (p != 0); | |
| 188 break; | |
| 189 } | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 #ifdef EXTERNAL_CODECS | |
| 194 if (!created && externalCodecs) | |
| 195 for (i = 0; i < (UInt32)externalCodecs->Size(); i++) | |
| 196 { | |
| 197 const CCodecInfoEx &codec = (*externalCodecs)[i]; | |
| 198 if (codec.Id == methodId) | |
| 199 { | |
| 200 if (encode) | |
| 201 { | |
| 202 if (codec.EncoderIsAssigned) | |
| 203 { | |
| 204 if (codec.IsSimpleCodec()) | |
| 205 { | |
| 206 HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder,
(void **)&coder); | |
| 207 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E
_CLASSNOTAVAILABLE) | |
| 208 return result; | |
| 209 if (!coder) | |
| 210 { | |
| 211 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void *
*)&filter)); | |
| 212 } | |
| 213 } | |
| 214 else | |
| 215 { | |
| 216 RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)
&coder2)); | |
| 217 } | |
| 218 break; | |
| 219 } | |
| 220 } | |
| 221 else | |
| 222 if (codec.DecoderIsAssigned) | |
| 223 { | |
| 224 if (codec.IsSimpleCodec()) | |
| 225 { | |
| 226 HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder,
(void **)&coder); | |
| 227 if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E
_CLASSNOTAVAILABLE) | |
| 228 return result; | |
| 229 if (!coder) | |
| 230 { | |
| 231 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void *
*)&filter)); | |
| 232 } | |
| 233 } | |
| 234 else | |
| 235 { | |
| 236 RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)
&coder2)); | |
| 237 } | |
| 238 break; | |
| 239 } | |
| 240 } | |
| 241 } | |
| 242 #endif | |
| 243 | |
| 244 if (onlyCoder && filter) | |
| 245 { | |
| 246 CFilterCoder *coderSpec = new CFilterCoder; | |
| 247 coder = coderSpec; | |
| 248 coderSpec->Filter = filter; | |
| 249 } | |
| 250 return S_OK; | |
| 251 } | |
| 252 | |
| 253 HRESULT CreateCoder( | |
| 254 DECL_EXTERNAL_CODECS_LOC_VARS | |
| 255 CMethodId methodId, | |
| 256 CMyComPtr<ICompressCoder> &coder, | |
| 257 CMyComPtr<ICompressCoder2> &coder2, | |
| 258 bool encode) | |
| 259 { | |
| 260 CMyComPtr<ICompressFilter> filter; | |
| 261 return CreateCoder( | |
| 262 EXTERNAL_CODECS_LOC_VARS | |
| 263 methodId, | |
| 264 filter, coder, coder2, encode, true); | |
| 265 } | |
| 266 | |
| 267 HRESULT CreateCoder( | |
| 268 DECL_EXTERNAL_CODECS_LOC_VARS | |
| 269 CMethodId methodId, | |
| 270 CMyComPtr<ICompressCoder> &coder, bool encode) | |
| 271 { | |
| 272 CMyComPtr<ICompressFilter> filter; | |
| 273 CMyComPtr<ICompressCoder2> coder2; | |
| 274 return CreateCoder( | |
| 275 EXTERNAL_CODECS_LOC_VARS | |
| 276 methodId, | |
| 277 coder, coder2, encode); | |
| 278 } | |
| 279 | |
| 280 HRESULT CreateFilter( | |
| 281 DECL_EXTERNAL_CODECS_LOC_VARS | |
| 282 CMethodId methodId, | |
| 283 CMyComPtr<ICompressFilter> &filter, | |
| 284 bool encode) | |
| 285 { | |
| 286 CMyComPtr<ICompressCoder> coder; | |
| 287 CMyComPtr<ICompressCoder2> coder2; | |
| 288 return CreateCoder( | |
| 289 EXTERNAL_CODECS_LOC_VARS | |
| 290 methodId, | |
| 291 filter, coder, coder2, encode, false); | |
| 292 } | |
| OLD | NEW |