/**************************************************************************
* *
* This code has been developed by Andrea Graziani. Those intending to *
* use this software module in hardware or software products are advised *
* that its use may infringe existing patents or copyrights, and any such *
* use would be at such party's own risk. The original developer of this *
* software module and his/her company, and subsequent editors and their *
* companies (including Project Mayo), will have no liability for use of *
* this software or modifications or derivatives thereof. *
* *
* Project Mayo gives users of the Codec and Filter a license to this *
* software module or modifications thereof for use in hardware or *
* software products claiming conformance to the MPEG-4 Video Standard *
* as described in the Open DivX license. *
* *
* The complete Open DivX license can be found at *
* http://www.projectmayo.com/opendivx/license.php *
* *
**************************************************************************/
/**
* Copyright (C) 2001 - Project Mayo
*
* Andrea Graziani
*
* DivX Advanced Research Center <darc@projectmayo.com>
*
**/
// divxfilter.cpp //
#include <windows.h>
#include <streams.h>
#include <dvdmedia.h>
#include <initguid.h>
#include "decore.h"
#include "divxuid.h"
#include "divxfilter.h"
#include "divxfilterproperties.h"
/**
* declaration of filter information
**/
// setup data
const AMOVIESETUP_MEDIATYPE sudPinInTypes[4] =
{
{ // Type 0
&MEDIATYPE_Video,
&CLSID_DivX
},
{ // Type 1
&MEDIATYPE_Video,
&CLSID_DivX_U
},
{ // Type 2
&MEDIATYPE_Video,
&CLSID_DivX_
},
{ // Type 3
&MEDIATYPE_Video,
&CLSID_DivX__U
}
};
const AMOVIESETUP_MEDIATYPE sudPinOutTypes[1] =
{
&MEDIATYPE_Video,
&MEDIASUBTYPE_NULL
};
const AMOVIESETUP_PIN psudPins[] =
{
{
L"Input", // String pin name
FALSE, // Is it rendered
FALSE, // Is it an output
FALSE,
FALSE,
&CLSID_NULL, // Connects to filter
L"Output", // Connects to pin
4, // Number of types
&sudPinInTypes[0] // The pin details
},
{
L"Output", // String pin name
FALSE, // Is it rendered
TRUE, // Is it an output
FALSE,
FALSE,
&CLSID_NULL, // Connects to filter
L"Input", // Connects to pin
1, // Number of types
&sudPinOutTypes[0] // The pin details
}
};
const AMOVIESETUP_FILTER sudDivXReg =
{
&CLSID_DivX, // Filter CLSID
L"OpenDivX Decoder Filter", // Filter name
MERIT_PREFERRED, // Its merit
2, // Number of pins
psudPins // Pin details
};
/**
* declaration of filter template
**/
// List of class IDs and creator functions for the class factory. This
// provides the link between the OLE entry point in the DLL and an object
// being created. The class factory will call the static CreateInstance
CFactoryTemplate g_Templates[2] =
{
{
L"OpenDivX Decoder Filter", // Filter name
&CLSID_DivX, // Filter CLSID
DivXFilter::CreateInstance, // Creation function
NULL, //
&sudDivXReg // Self-registration information
},
{
L"OpenDivX Decoder Filter Properties Page",
&CLSID_DivXPropertiesPage,
DivXFilterProperties::CreateInstance
}
};
int g_cTemplates = sizeof(g_Templates)/(sizeof(g_Templates[0]));
//
// CreateInstance
//
CUnknown * WINAPI DivXFilter::CreateInstance(LPUNKNOWN lpunk, HRESULT * phr)
{
DivXFilter * pNewObject = new DivXFilter(NAME("OpenDivX Decoder Filter"), lpunk, phr);
if (pNewObject == NULL) {
*phr = E_OUTOFMEMORY;
}
return pNewObject;
} // CreateInstance
//
// NonDelegatingQueryInterface
//
STDMETHODIMP DivXFilter::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
{
if (riid == IID_IDivXFilterInterface) {
return GetInterface((IDivXFilterInterface *) this, ppv);
}
else if (riid == IID_ISpecifyPropertyPages) {
return GetInterface((ISpecifyPropertyPages *) this, ppv);
}
return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
} // NonDelegatingQueryInterface
/**
* implementation of DllRegistrerServer
**/
// the dll that export this component must contain this function
//
STDAPI DllRegisterServer(void)
{
HRESULT hr = AMovieDllRegisterServer2(TRUE);
if ( FAILED(hr) )
return hr;
IFilterMapper2 *pFM2 = 0;
hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
IID_IFilterMapper2, (void **) &pFM2);
if ( FAILED(hr) )
return hr;
REGFILTER2 rf2;
rf2.dwVersion = 1;
rf2.dwMerit = MERIT_PREFERRED;
rf2.cPins = NUMELMS(psudPins);
rf2.rgPins = psudPins;
hr = pFM2->RegisterFilter(CLSID_DivX,
L"OpenDivX Decoder Filter",
NULL,
&CLSID_AVIDec,
L"CLSID_DivXDeux",
&rf2);
pFM2->Release();
return hr;
} // DllRegisterServer
STDAPI DllUnregisterServer(void)
{
HRESULT hr = AMovieDllRegisterServer2(FALSE);
if ( FAILED(hr) )
return hr;
IFilterMapper2 * pFM2 = 0;
hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
IID_IFilterMapper2, (void **) &pFM2);
if ( FAILED(hr) )
return hr;
if (pFM2 != 0) {
hr = pFM2->UnregisterFilter(&CLSID_AVIDec,
NULL, CLSID_DivX);
pFM2->Release();
}
return S_OK;
} // DllUnregisterServer
/**
* override of functions
**/
// determine if the proposed input is valid
//
HRESULT DivXFilter::CheckInputType(const CMediaType * pmtIn)
{
DbgLog((LOG_TRACE, 2, TEXT("DivXFilter::CheckInputType")));
if ( (*pmtIn->Type() != MEDIATYPE_Video) )
return E_INVALIDARG;
VIDEOINFO * pvi = (VIDEOINFO *) pmtIn->Format();
m_DecParam.y_dim = (pvi->bmiHeader.biHeight > 0) ?
pvi->bmiHeader.biHeight : -pvi->bmiHeader.biHeight;
m_DecParam.x_dim = pvi->bmiHeader.biWidth;
return S_OK;
} // CheckInputType
HRESULT DivXFilter::StartStreaming()
{
return S_OK;
} // StartStreaming
HRESULT DivXFilter::StopStreaming()
{
return S_OK;
} // StopStreaming
// performs my desired transformation on input media
//
HRESULT DivXFilter::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
if (m_iInitialized == 0)
{
decore(1, DEC_OPT_MEMORY_REQS, &m_DecParam, &m_DecMemReqs);
m_DecParam.buffers.mp4_edged_ref_buffers = malloc(m_DecMemReqs.mp4_edged_ref_buffers_size);
m_DecParam.buffers.mp4_edged_for_buffers = malloc(m_DecMemReqs.mp4_edged_for_buffers_size);
m_DecParam.buffers.mp4_display_buffers = malloc(m_DecMemReqs.mp4_display_buffers_size);
m_DecParam.buffers.mp4_state = malloc(m_DecMemReqs.mp4_state_size);
m_DecParam.buffers.mp4_tables = malloc(m_DecMemReqs.mp4_tables_size);
m_DecParam.buffers.mp4_stream = malloc(m_DecMemReqs.mp4_stream_size);
memset(m_DecParam.buffers.mp4_state, 0, m_DecMemReqs.mp4_state_size);
memset(m_DecParam.buffers.mp4_tables, 0, m_DecMemReqs.mp4_tables_size);
memset(m_DecParam.buffers.mp4_stream, 0, m_DecMemReqs.mp4_stream_size);
decore((long) this, DEC_OPT_INIT, &m_DecParam, NULL);
put_PPLevel(90);
m_iInitialized = 1;
}
DEC_FRAME dec_frame;
BYTE * input_buffer, * output_buffer;
if (pIn->GetPointer(&input_buffer) != S_OK)
return S_OK; // not valid pointer, forgot it!
if (pOut->GetPointer(&output_buffe
评论0