/* * CMP compression method */ #include #include "CODEC.h" #ifdef CODEC_CMP #include "ltmm.h" #include "ILMDSKernel2.h" #include "IMCMPCodec2.h" #include IltmmCompressors *gp_Compressors; IltmmConvert *gp_Convert; ILMDSKernel2 *gp_Kernel; bool b_ContextCreated = false; long l_CodecIndex; bool CMP_SetEncodingMethod() { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ VARIANT_BOOL f; BSTR bstr, bstrKernel1, bstrKernel2; long i; HRESULT hr; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ // Create kernel and unlock video filters on computer level bstrKernel1 = SysAllocString(L"All video filters serial number"); bstrKernel2 = SysAllocString(L"Application ID"); hr = CoCreateInstance(CLSID_LMDSKernel2, NULL, CLSCTX_INPROC_SERVER, IID_ILMDSKernel2, (void**) &gp_Kernel); gp_Kernel->UnlockModule(bstrKernel1, UNLOCK_COMPUTER, bstrKernel2); SysFreeString(bstrKernel1); SysFreeString(bstrKernel2); // Create the convert object if (!gp_Convert) { CoInitialize(NULL); hr = CoCreateInstance(CLSID_ltmmConvert, NULL, CLSCTX_INPROC_SERVER, IID_IltmmConvert, (void**) &gp_Convert); if (FAILED(hr)) return false; } // Select the LEAD video compressor gp_Convert->get_VideoCompressors(&gp_Compressors); bstr = SysAllocString(L"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\LEAD MCMP/MJPEG Codec (2.0)"); gp_Compressors->Find(bstr, &l_CodecIndex); SysFreeString(bstr); if(l_CodecIndex < 0) { // Compressor isn't registered gp_Compressors->Release(); return false; } gp_Compressors->put_Selection(l_CodecIndex); gp_Compressors->Release(); // Assign the notification window (NULL not to receive messages) gp_Convert->SetNotifyWindow(NULL, 0); return true; } void *CMP_Encode_INIT(MAP *PPicture) { /*~~~~~~~~~~~~~~~~~~~~~~~*/ IltmmCompressor *pCompressor; static bool b_CompressionSet = false; /*~~~~~~~~~~~~~~~~~~~~~~~*/ // Create converter and set compressor if necessary if (!b_CompressionSet) if (!CMP_SetEncodingMethod()) return NULL; b_ContextCreated = true; // Get appropriate compressor gp_Compressors->Item(l_CodecIndex, &pCompressor); return (void *)pCompressor; } u32 CMP_Encode_FRAME(void *H, MAP *PPicture, char *Buffer, u32 FROMSCRATCH) { /*~~~~~~~~~~~~~~~~~~~~~~~*/ //IltmmMemory *pSource = NULL, *pTarget = NULL; IltmmSampleSource *pSampleSource = NULL; IltmmSampleTarget *pSampleTarget = NULL; IltmmMediaTypeDisp *pMediaType = NULL; HRESULT hr; long l_State; SAFEARRAY sa; VARIANT var; IUnknown* pUnk = NULL; VARIANT_BOOL f; BSTR bstr; SAFEARRAY* psaSource; SAFEARRAY* psaTarget; long index[1]; IltmmVCRControl *pVCR; u32 i,j; /*~~~~~~~~~~~~~~~~~~~~~~~*/ /* // Create the source and target objects (they are samples) CoCreateInstance(CLSID_ltmmSampleSource, NULL, CLSCTX_INPROC_SERVER, IID_IltmmSampleSource, (void**) &pSampleSource); CoCreateInstance(CLSID_ltmmSampleTarget, NULL, CLSCTX_INPROC_SERVER, IID_IltmmSampleTarget, (void**) &pSampleTarget); CoCreateInstance(CLSID_ltmmMediaType, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMediaTypeDisp, (void**) &pMediaType); CoCreateInstance(CLSID_ltmmMemory, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMemory, (void**) &pSource); CoCreateInstance(CLSID_ltmmMemory, NULL, CLSCTX_INPROC_SERVER, IID_IltmmMemory, (void**) &pTarget); // set type to MEDIATYPE_Video bstr = SysAllocString(L"{73646976-0000-0010-8000-00AA00389B71}"); hr = pMediaType->put_Type (bstr); SysFreeString(bstr); if(FAILED(hr)) goto error; bstr = SysAllocString(L"{e436eb7d-524f-11ce-9f53-0020af0ba770}"); hr = pMediaType->put_Type (bstr); SysFreeString(bstr); // set subtype to MEDIASUBTYPE_RGB24 bstr = SysAllocString(L"{e436eb7d-524f-11ce-9f53-0020af0ba770}"); hr = pMediaType->put_Subtype (bstr); SysFreeString(bstr); // set the accepted media type //hr = pSampleSource->SetMediaType(pMediaType); hr = pSampleTarget->SetAcceptedMediaType(pMediaType); // Set the source buffer size //pSource->put_BufferSize(PPicture->SX * PPicture->SY); // Pass data from the arr BYTE array... memset(&sa, 0, sizeof(sa)); sa.cbElements = sizeof(unsigned char); sa.cDims = 1; sa.fFeatures = (FADF_AUTO | FADF_FIXEDSIZE); sa.pvData = (char *)PPicture->BASE; //data to fill sa.rgsabound[0].cElements = PPicture->SX * PPicture->SY; //pSource->SetData(0, PPicture->SX * PPicture->SY, var); pMediaType->SetFormatData(sizeof(VIDEOINFOHEADER), var); // Fixed image size samples pMediaType->put_FixedSizeSamples(VARIANT_TRUE); pMediaType->put_SampleSize(PPicture->SX * PPicture->SY); // Set the source media type hr = pSampleSource->SetMediaType(pMediaType); pMediaType->Release(); pMediaType = NULL; */ // Create the source array psaSource = SafeArrayCreateVector(VT_UI1, 0, PPicture->SX * PPicture->SY); if (!psaSource) { gp_Convert->ResetSource(); SafeArrayDestroy(psaSource); return E_OUTOFMEMORY; } // Fill the source array with the image to convert SafeArrayAccessData(psaSource, (void **) &PPicture->BASE); for (i = 0 ; i < PPicture->SY ; i += PPicture->PITCH) { for (j = 0 ; j < PPicture->SX ; j++) { index[0] = j + i*PPicture->PITCH; SafeArrayPutElement(psaSource, index, (void *) &PPicture->BASE[index[0]]); } } SafeArrayUnaccessData(psaSource); // Assign the source array VariantInit(&var); V_VT(&var) = (VT_ARRAY | VT_UI1); V_ARRAY(&var) = psaSource; // Set input array gp_Convert->ResetSource(); hr = gp_Convert->put_SourceArray(var); if(FAILED(hr)) return -1; /* ~~~~~~~~~~~~ Code to use for internet targeting ~~~~~~~~~~~~*/ // Set the server address as a target file /*BSTR sServer; char *server; OLECHAR *server2; sprintf(server, "%d:255.255.255.255", port); sServer = SysAllocString(server); // use the default port, 27015 pCapture->put_TargetFile(sServer); SysFreeString(sServer); // Change the NET Mux settings if needed: // Get the mux object and query for the interface IUnknown* pUnk = NULL; ILMNetMux* pMux = NULL; pCapture->GetSubObject(ltmmCapture_Object_TargetFilter, &pUnk); pUnk->QueryInterface(IID_ILMNetMux, (void**) &pMux); pUnk->Release(); // This is a live source pMux->put_LiveSource(VARIANT_TRUE); // I can afford 128 kbps only pMux->put_BitRateLimit(128*1024); pMux->Release();*/ /* ~~~~~~~~~~ End of code to use for internet targeting ~~~~~~~~~~*/ // Create the target array psaTarget = SafeArrayCreateVector(VT_UI1, 0, 0); if (!psaTarget) { gp_Convert->ResetSource(); gp_Convert->ResetTarget(); SafeArrayDestroy(psaSource); SafeArrayDestroy(psaTarget); return E_OUTOFMEMORY; } // Assign the target array VariantInit(&var); V_VT(&var) = (VT_ARRAY | VT_UI1); V_ARRAY(&var) = psaTarget; // Set output array gp_Convert->ResetTarget(); hr = gp_Convert->put_TargetArray(var); if(FAILED(hr)) return -1; // Target format is a network stream // gp_Convert->put_TargetFormat(ltmmCapture_TargetFormat_NET); // gp_Convert->put_TargetFormat(ltmmCapture_TargetFormat_Avi); gp_Convert->put_TargetFormat(ltmmCapture_TargetFormat_Stream); // Get network multiplexer //gp_Target->GetSubObject(ltmmCapture_Object_TargetFilter, &pUnk); long source, target; gp_Convert->get_SourceType(&source); gp_Convert->get_TargetType(&target); gp_Convert->get_State(&l_State); // start the conversion if (l_State != ltmmConvert_State_NotReady && l_State != ltmmConvert_State_Running) { hr = gp_Convert->StartConvert(); if(FAILED(hr)) return -1; } // Don't need the source anymore SafeArrayDestroy(psaSource); Buffer = (char *)psaTarget->pvData; return sizeof(Buffer); } void CMP_Encode_CLOSE(void *H) { /*~~~~~~~~~~~~~~~~~~*/ BSTR bstr; /*~~~~~~~~~~~~~~~~~~*/ bstr = SysAllocString(L"All video filters serial number"); gp_Kernel->LockModules(bstr, LOCK_COMPUTER); gp_Kernel->Release(); CoUninitialize(); } void *Encode_INIT(MAP *PPicture) { return CMP_Encode_INIT(PPicture); } u32 Encode_FRAME(void *H, MAP *PPicture, char *Buffer, u32 FROMSCRATCH) { return CMP_Encode_FRAME(H, PPicture, Buffer, FROMSCRATCH); } /*u32 Encode_FRAME(void *H, MAP *PPicture, char *Buffer, unsigned short port, u32 FROMSCRATCH) { return CMP_Encode_FRAME(H, PPicture, Buffer, port, FROMSCRATCH); }*/ void Encode_CLOSE(void *H) { CMP_Encode_CLOSE(H); } #endif