JD2022-TU1/main/extern/Camcam/LIBS/X264 - Lib/CMP_Encoder.cpp

303 lines
8.1 KiB
C++

/*
* CMP compression method
*/
#include <stdint.h>
#include "CODEC.h"
#ifdef CODEC_CMP
#include "ltmm.h"
#include "ILMDSKernel2.h"
#include "IMCMPCodec2.h"
#include <amvideo.h>
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