1 #include "DMO_Filter.h"
2 #include "driver.h"
3 #include "com.h"
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include "win32.h" // printf macro
8 
9 void trapbug();
10 typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**);
11 
DMO_Filter_Destroy(DMO_Filter * This)12 void DMO_Filter_Destroy(DMO_Filter* This)
13 {
14     if (This->m_pOptim)
15 	This->m_pOptim->vt->Release((IUnknown*)This->m_pOptim);
16     if (This->m_pInPlace)
17 	This->m_pInPlace->vt->Release((IUnknown*)This->m_pInPlace);
18     if (This->m_pMedia)
19 	This->m_pMedia->vt->Release((IUnknown*)This->m_pMedia);
20 
21     free(This);
22     CodecRelease();
23 }
24 
DMO_FilterCreate(const char * dllname,const GUID * id,DMO_MEDIA_TYPE * in_fmt,DMO_MEDIA_TYPE * out_fmt)25 DMO_Filter* DMO_FilterCreate(const char* dllname, const GUID* id,
26 			     DMO_MEDIA_TYPE* in_fmt,
27 			     DMO_MEDIA_TYPE* out_fmt)
28 {
29     HRESULT hr = 0;
30     const char* em = NULL;
31     DMO_Filter* This = (DMO_Filter*) malloc(sizeof(DMO_Filter));
32     if (!This)
33 	return NULL;
34 
35     memset(This, 0, sizeof(DMO_Filter));
36     CodecAlloc();
37 
38     //This->Start = DS_Filter_Start;
39     //This->Stop = DS_Filter_Stop;
40 
41     for (;;)
42     {
43 	GETCLASS func;
44 	struct IClassFactory* factory = NULL;
45 	struct IUnknown* object = NULL;
46         unsigned int i;
47         unsigned long inputs, outputs;
48 
49 	This->m_iHandle = LoadLibraryA(dllname);
50 	if (!This->m_iHandle)
51 	{
52 	    em = "could not open DMO DLL";
53 	    break;
54 	}
55 	func = (GETCLASS)GetProcAddress((unsigned)This->m_iHandle, "DllGetClassObject");
56 	if (!func)
57 	{
58 	    em = "illegal or corrupt DMO DLL";
59 	    break;
60 	}
61 //trapbug();
62 	hr = func(id, &IID_IClassFactory, (void**)&factory);
63 	if (hr || !factory)
64 	{
65 	    em = "no such class object";
66 	    break;
67 	}
68 	hr = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
69 	factory->vt->Release((IUnknown*)factory);
70 	if (hr || !object)
71 	{
72 	    em = "class factory failure";
73 	    break;
74 	}
75 	hr = object->vt->QueryInterface(object, &IID_IMediaObject, (void**)&This->m_pMedia);
76 	if (hr == 0)
77 	{
78             /* query for some extra available interface */
79 	    HRESULT r = object->vt->QueryInterface(object, &IID_IMediaObjectInPlace, (void**)&This->m_pInPlace);
80             if (r == 0 && This->m_pInPlace)
81 		printf("DMO dll supports InPlace - PLEASE REPORT to developer\n");
82 	    r = object->vt->QueryInterface(object, &IID_IDMOVideoOutputOptimizations, (void**)&This->m_pOptim);
83 	    if (r == 0 && This->m_pOptim)
84 	    {
85                 unsigned long flags;
86 		r = This->m_pOptim->vt->QueryOperationModePreferences(This->m_pOptim, 0, &flags);
87 		printf("DMO dll supports VO Optimizations %ld %lx\n", r, flags);
88 		if (flags & DMO_VOSF_NEEDS_PREVIOUS_SAMPLE)
89 		    printf("DMO dll might use previous sample when requested\n");
90 	    }
91 	}
92 	object->vt->Release((IUnknown*)object);
93 	if (hr || !This->m_pMedia)
94 	{
95 	    em = "object does not provide IMediaObject interface";
96 	    break;
97 	}
98 	hr = This->m_pMedia->vt->SetInputType(This->m_pMedia, 0, in_fmt, 0);
99 	if (hr)
100 	{
101 	    em = "input format not accepted";
102 	    break;
103 	}
104 
105 	if (0) {
106 	    DMO_MEDIA_TYPE dmo;
107             /* VIDEOINFOHEADER* vi; -- not used */
108 	    memset(&dmo, 0, sizeof(dmo));
109 	    i = This->m_pMedia->vt->GetOutputType(This->m_pMedia, 0, 2, &dmo);
110 	    printf("GetOutputType %x \n", i);
111 	    printf("DMO  0x%x (%.4s) 0x%x (%.4s)\n"
112 	    //printf("DMO  0x%x 0x%x\n"
113 		   ":: fixszsamp:%d tempcomp:%d  sampsz:%ld\n"
114 		   ":: formtype: 0x%x\n"
115 		   ":: unk %p  cbform: %ld  pbform:%p\n",
116 		   dmo.majortype.f1,
117 		   (const char*)&dmo.majortype.f1,
118 		   dmo.subtype.f1,
119 		   (const char*)&dmo.subtype.f1,
120 		   dmo.bFixedSizeSamples, dmo.bTemporalCompression,
121 		   dmo.lSampleSize,
122 		   dmo.formattype.f1,
123                    dmo.pUnk, dmo.cbFormat, dmo.pbFormat
124 		  );
125 /*          vi =  (VIDEOINFOHEADER*) dmo.pbFormat;
126 	    vi =  (VIDEOINFOHEADER*) out_fmt->pbFormat;
127 	    for (i = 0; i < out_fmt->cbFormat; i++)
128                 printf("BYTE %d  %02x  %02x\n", i, ((uint8_t*)dmo.pbFormat)[i], ((uint8_t*)out_fmt->pbFormat)[i]);
129 */
130 	}
131 
132 	hr = This->m_pMedia->vt->SetOutputType(This->m_pMedia, 0, out_fmt, 0);
133 	if (hr)
134 	{
135 	    em = "output format no accepted";
136 	    break;
137 	}
138 
139 	inputs = outputs = 0;
140 	hr = This->m_pMedia->vt->GetOutputSizeInfo(This->m_pMedia, 0, &inputs, &outputs);
141 	printf("GetOutput r=0x%lx   size:%ld  align:%ld\n", hr, inputs, outputs);
142 
143 	// This->m_pMedia->vt->AllocateStreamingResources(This->m_pMedia);
144 	hr = This->m_pMedia->vt->GetStreamCount(This->m_pMedia, &inputs, &outputs);
145 	printf("StreamCount r=0x%lx  %ld  %ld\n", hr, inputs, outputs);
146 
147         break;
148     }
149     if (em)
150     {
151         DMO_Filter_Destroy(This);
152 	printf("IMediaObject ERROR: %p  %s (0x%lx : %ld)\n", em, em ? em : "", hr, hr);
153 	This = 0;
154     }
155     return This;
156 }
157