8294
|
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
|
|
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
|
|
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;
|
|
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 }
|