Mercurial > mplayer.hg
comparison loader/dshow/DS_VideoDec.c @ 1545:da26060c81ef
big avifile sync - from now we have common code
author | arpi |
---|---|
date | Thu, 16 Aug 2001 00:50:02 +0000 |
parents | 9525bff8bea8 |
children | 076c27342828 |
comparison
equal
deleted
inserted
replaced
1544:558c1b03b8d0 | 1545:da26060c81ef |
---|---|
1 /******************************************************** | 1 #include "guids.h" |
2 #include "interfaces.h" | |
2 | 3 |
3 DirectShow Video decoder implementation | 4 #include "DS_VideoDecoder.h" |
4 Copyright 2000 Eugene Kuznetsov (divx@euro.ru) | 5 #include <wine/winerror.h> |
5 Converted C++ --> C :) by A'rpi/ESP-team | 6 #include <libwin32.h> |
7 //#include <cpuinfo.h> | |
6 | 8 |
7 *********************************************************/ | |
8 | |
9 //#include <config.h> | |
10 | |
11 //#include "DS_VideoDecoder.h" | |
12 //#include <string.h> | |
13 using namespace std; | |
14 #include <stdlib.h> | |
15 #include <except.h> | |
16 #define __MODULE__ "DirectShow_VideoDecoder" | |
17 | |
18 | |
19 #include <errno.h> | |
20 #ifdef HAVE_MALLOC_H | |
21 #include <malloc.h> | |
22 #endif | |
23 //#include <loader.h> | |
24 //#include <wine/winbase.h> | |
25 #include <stdio.h> | |
26 #include <unistd.h> | 9 #include <unistd.h> |
27 #include <fcntl.h> | 10 #include <fcntl.h> |
28 #include <strstream> | 11 #include <errno.h> |
29 #include <dlfcn.h> | |
30 #include <sys/types.h> | 12 #include <sys/types.h> |
31 #include <sys/mman.h> | 13 #include <sys/mman.h> |
14 #include <cstdio> | |
15 #include <iostream> | |
16 #include <strstream> | |
32 | 17 |
33 #include <registry.h> | 18 #include <registry.h> |
34 #include <wine/winreg.h> | 19 //#include <wine/winreg.h> |
35 | |
36 #include "guids.h" | |
37 #include "interfaces.h" | |
38 #include "DS_Filter.h" | |
39 | |
40 #include "BitmapInfo.h" | |
41 | |
42 #include <string> | |
43 #include <default.h> | |
44 | 20 |
45 #include "DS_VideoDec.h" | 21 #include "DS_VideoDec.h" |
46 | 22 |
23 static void* _handle; // will be parameter later... | |
24 static char** _d_ptr; // will be parameter later... | |
47 | 25 |
48 extern "C" char* def_path; | 26 extern "C" void Setup_LDT_Keeper(); |
27 extern "C" void setup_FS_Segment(); | |
49 | 28 |
50 static char** m_destptr=0; | 29 extern "C" int DS_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEADER* format, int flip,char** d_ptr){ |
51 | 30 |
52 static DS_Filter* dsf=0; | 31 Setup_LDT_Keeper(); |
53 | 32 |
54 static AM_MEDIA_TYPE m_sOurType, m_sDestType; | 33 CodecInfo ci; |
55 static VIDEOINFOHEADER *m_sVhdr; | 34 ci.dll=dllname; |
56 static VIDEOINFOHEADER *m_sVhdr2; | 35 ci.guid=*guid; |
57 static void* m_pCust; | 36 |
37 DS_VideoDecoder* dec=new DS_VideoDecoder(ci, *format, flip); | |
38 | |
39 _d_ptr=d_ptr; | |
40 _handle=(void*)dec; | |
58 | 41 |
59 static BITMAPINFOHEADER *m_bh;//format of input data | |
60 static BitmapInfo m_decoder;//format of decoder output | |
61 static BitmapInfo m_obh; //format of returned frames | |
62 // CImage* m_outFrame; | |
63 | |
64 // int m_iState=0; | |
65 | |
66 extern "C" int DS_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEADER* format, int flip,char** d_ptr) | |
67 // :IVideoDecoder(info), m_sVhdr2(0) | |
68 { | |
69 | |
70 m_destptr=d_ptr; | |
71 | |
72 //m_outFrame=0; | |
73 //decpos = 0; | |
74 //playpos = 0; | |
75 //realtime = 0; | |
76 | |
77 try | |
78 { | |
79 m_bh=format; | |
80 memset(&m_obh, 0, sizeof(m_obh)); | |
81 m_obh.biSize=sizeof(m_obh); | |
82 | |
83 #if 0 | |
84 memset(&m_sVhdr, 0, sizeof(m_sVhdr)); | |
85 m_sVhdr.bmiHeader=m_bh; | |
86 m_sVhdr.rcSource.left=m_sVhdr.rcSource.top=0; | |
87 m_sVhdr.rcSource.right=m_sVhdr.bmiHeader.biWidth; | |
88 m_sVhdr.rcSource.bottom=m_sVhdr.bmiHeader.biHeight; | |
89 m_sVhdr.rcTarget=m_sVhdr.rcSource; | |
90 #else | |
91 unsigned bihs = (format->biSize < (int) sizeof(BITMAPINFOHEADER)) ? | |
92 sizeof(BITMAPINFOHEADER) : format->biSize; | |
93 bihs = sizeof(VIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER) + bihs; | |
94 | |
95 m_sVhdr = (VIDEOINFOHEADER*) new char[bihs]; | |
96 memset(m_sVhdr, 0, bihs); | |
97 memcpy(&m_sVhdr->bmiHeader, m_bh, m_bh->biSize); | |
98 | |
99 m_sVhdr->rcSource.left = m_sVhdr->rcSource.top = 0; | |
100 m_sVhdr->rcSource.right = m_sVhdr->bmiHeader.biWidth; | |
101 m_sVhdr->rcSource.bottom = m_sVhdr->bmiHeader.biHeight; | |
102 m_sVhdr->rcTarget = m_sVhdr->rcSource; | |
103 #endif | |
104 m_sOurType.majortype=MEDIATYPE_Video; | |
105 m_sOurType.subtype=MEDIATYPE_Video; | |
106 m_sOurType.subtype.f1=m_sVhdr->bmiHeader.biCompression; | |
107 m_sOurType.formattype=FORMAT_VideoInfo; | |
108 m_sOurType.bFixedSizeSamples=false; | |
109 m_sOurType.bTemporalCompression=true; | |
110 m_sOurType.pUnk=0; | |
111 // m_sOurType.cbFormat=sizeof(m_sVhdr); | |
112 // m_sOurType.pbFormat=(char*)&m_sVhdr; | |
113 m_sOurType.cbFormat = bihs; | |
114 m_sOurType.pbFormat = (char*)m_sVhdr; | |
115 | |
116 m_sVhdr2=(VIDEOINFOHEADER*)(new char[sizeof(VIDEOINFOHEADER)+12]); | |
117 // *m_sVhdr2=m_sVhdr; | |
118 memcpy(m_sVhdr2, m_sVhdr, sizeof(VIDEOINFOHEADER)+12); | |
119 m_sVhdr2->bmiHeader.biCompression=0; | |
120 m_sVhdr2->bmiHeader.biBitCount=24; | |
121 | |
122 memset(&m_sDestType, 0, sizeof(m_sDestType)); | |
123 m_sDestType.majortype=MEDIATYPE_Video; | |
124 m_sDestType.subtype=MEDIASUBTYPE_RGB24; | |
125 m_sDestType.formattype=FORMAT_VideoInfo; | |
126 m_sDestType.bFixedSizeSamples=true; | |
127 m_sDestType.bTemporalCompression=false; | |
128 m_sDestType.lSampleSize=abs(m_sVhdr2->bmiHeader.biWidth*m_sVhdr2->bmiHeader.biHeight* | |
129 ((m_sVhdr2->bmiHeader.biBitCount+7)/8)); | |
130 m_sVhdr2->bmiHeader.biSizeImage=m_sDestType.lSampleSize; | |
131 m_sDestType.pUnk=0; | |
132 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER); | |
133 m_sDestType.pbFormat=(char*)m_sVhdr2; | |
134 m_obh = *m_bh; | |
135 m_obh.setBits(24); | |
136 | |
137 HRESULT result; | |
138 | |
139 dsf=new DS_Filter(); | |
140 dsf->Create(dllname, guid, &m_sOurType, &m_sDestType); | |
141 | |
142 if(!flip) | |
143 { | |
144 m_sVhdr2->bmiHeader.biHeight*=-1; | |
145 m_obh.biHeight*=-1; | |
146 result=dsf->m_pOutputPin->vt->QueryAccept(dsf->m_pOutputPin, &m_sDestType); | |
147 if(result){ | |
148 printf("DShow: Decoder does not support upside-down frames"); | |
149 m_obh.biHeight*=-1; | |
150 } | |
151 } | |
152 | |
153 #if 0 | |
154 m_sVhdr2->bmiHeader.biBitCount=16; | |
155 m_sVhdr2->bmiHeader.biCompression=fccYUY2; | |
156 m_sDestType.subtype=MEDIASUBTYPE_YUY2; | |
157 result=dsf->m_pOutputPin->vt->QueryAccept(dsf->m_pOutputPin, &m_sDestType); | |
158 // if(!result) caps=(CAPS)(caps | CAP_YUY2); | |
159 #endif | |
160 | |
161 m_sVhdr2->bmiHeader.biBitCount=24; | |
162 m_sVhdr2->bmiHeader.biCompression=0; | |
163 m_sDestType.subtype=MEDIASUBTYPE_RGB24; | |
164 m_decoder=m_obh; | |
165 //qual = 0-1; | |
166 } | |
167 catch(FatalError& error) | |
168 { | |
169 delete[] m_sVhdr2; | |
170 return 1; | |
171 } | |
172 return 0; | 42 return 0; |
173 } | 43 } |
174 | 44 |
175 extern "C" void DS_VideoDecoder_Start(){ | 45 extern "C" void DS_VideoDecoder_Start(){ |
176 if(dsf->m_iState!=1) return; | 46 DS_VideoDecoder* dec=(DS_VideoDecoder*) _handle; |
177 dsf->Start(); | 47 dec->StartInternal(); |
178 | |
179 ALLOCATOR_PROPERTIES props, props1; | |
180 props.cBuffers=1; | |
181 props.cbBuffer=1024*1024; //m_sDestType.lSampleSize;//don't know how to do this correctly | |
182 props.cbAlign=props.cbPrefix=0; | |
183 dsf->m_pAll->vt->SetProperties(dsf->m_pAll, &props, &props1); | |
184 dsf->m_pAll->vt->Commit(dsf->m_pAll); | |
185 | |
186 // m_outFrame=new CImage(&m_decoder,(unsigned char *)malloc(m_sDestType.lSampleSize),false); | |
187 //m_outFrame=new CImage(&m_decoder, 0, false); | |
188 // printf("Datap %x\n",m_outFrame->getaddr()); | |
189 | |
190 | |
191 // dsf->m_pOurOutput->SetFramePointer((char **)m_outFrame->getaddr()); //!FIXME! | |
192 dsf->m_pOurOutput->SetFramePointer(m_destptr); //!FIXME! | |
193 | |
194 // filling = realtime; | |
195 | |
196 dsf->m_iState=2; | |
197 return; | |
198 } | 48 } |
199 | 49 |
200 extern "C" void DS_VideoDecoder_Stop(){ | 50 extern "C" void DS_VideoDecoder_Stop(){ |
201 if(dsf->m_iState!=2) return; | 51 DS_VideoDecoder* dec=(DS_VideoDecoder*) _handle; |
202 dsf->Stop(); | 52 dec->StopInternal(); |
203 // dsf->m_pOurOutput->SetFramePointer(0); | |
204 // free(m_outFrame->data()); | |
205 //m_outFrame->release();//just in case | |
206 //m_outFrame=0; | |
207 // FlushCache(); | |
208 dsf->m_iState=1; | |
209 return; | |
210 } | 53 } |
211 | 54 |
212 extern "C" void DS_VideoDecoder_Restart(){ | 55 extern "C" void DS_VideoDecoder_Restart(){ |
213 if(dsf->m_iState!=2) return; | |
214 | |
215 dsf->Stop(); | |
216 dsf->Start(); | |
217 | |
218 ALLOCATOR_PROPERTIES props, props1; | |
219 props.cBuffers=1; | |
220 props.cbBuffer=m_sDestType.lSampleSize;//don't know how to do this correctly | |
221 props.cbAlign=props.cbPrefix=0; | |
222 dsf->m_pAll->vt->SetProperties(dsf->m_pAll, &props, &props1); | |
223 dsf->m_pAll->vt->Commit(dsf->m_pAll); | |
224 } | 56 } |
225 | 57 |
226 extern "C" void DS_VideoDecoder_Close(){ | 58 extern "C" void DS_VideoDecoder_Close(){ |
227 if(dsf->m_iState==0) return; | |
228 if(dsf->m_iState==2) DS_VideoDecoder_Stop(); | |
229 delete[] m_sVhdr2; | |
230 // delete m_outFrame; | |
231 } | 59 } |
232 | 60 |
233 extern "C" int DS_VideoDecoder_DecodeFrame(char* src, int size, int is_keyframe, int render){ | 61 extern "C" int DS_VideoDecoder_DecodeFrame(char* src, int size, int is_keyframe, int render){ |
234 | 62 DS_VideoDecoder* dec=(DS_VideoDecoder*) _handle; |
235 if(!size)return 0; | 63 CImage image; |
236 | 64 image.ptr=*_d_ptr; |
237 m_bh->biSizeImage=size; | 65 return dec->DecodeInternal((void*)src,(size_t)size,is_keyframe,&image); |
238 | |
239 IMediaSample* sample=0; | |
240 //printf("GetBuffer... (m_pAll=%X) ",dsf->m_pAll);fflush(stdout); | |
241 dsf->m_pAll->vt->GetBuffer(dsf->m_pAll, &sample, 0, 0, 0); | |
242 //printf("OK!\n"); | |
243 if(!sample) | |
244 { | |
245 Debug cerr<<"ERROR: null sample"<<endl; | |
246 return -1; | |
247 } | |
248 char* ptr; | |
249 //printf("GetPtr...");fflush(stdout); | |
250 sample->vt->GetPointer(sample, (BYTE **)&ptr); | |
251 //printf("OK!\n"); | |
252 memcpy(ptr, src, size); | |
253 //printf("memcpy OK!\n"); | |
254 sample->vt->SetActualDataLength(sample, size); | |
255 //printf("SetActualDataLength OK!\n"); | |
256 sample->vt->SetSyncPoint(sample, is_keyframe); | |
257 //printf("SetSyncPoint OK!\n"); | |
258 sample->vt->SetPreroll(sample, !render); | |
259 // sample->vt->SetMediaType(sample, &m_sOurType); | |
260 int result=dsf->m_pImp->vt->Receive(dsf->m_pImp, sample); | |
261 if(result) | |
262 printf("Error putting data into input pin %x\n", result); | |
263 | |
264 sample->vt->Release((IUnknown*)sample); | |
265 | |
266 return 0; | |
267 } | 66 } |
268 | 67 |
269 extern "C" int DS_VideoDecoder_SetDestFmt(int bits, int csp){ | 68 extern "C" int DS_VideoDecoder_SetDestFmt(int bits, int csp){ |
270 if(dsf->m_iState==0) return -1; | 69 DS_VideoDecoder* dec=(DS_VideoDecoder*) _handle; |
271 // if(!CImage::supported(csp, bits)) return -1; | 70 return dec->SetDestFmt(bits,(fourcc_t)csp); |
272 HRESULT result; | |
273 // BitmapInfo temp=m_obh; | |
274 if(csp==0) | |
275 { | |
276 switch(bits) | |
277 { | |
278 case 15: | |
279 m_sDestType.subtype=MEDIASUBTYPE_RGB555; | |
280 break; | |
281 case 16: | |
282 m_sDestType.subtype=MEDIASUBTYPE_RGB565; | |
283 break; | |
284 case 24: | |
285 m_sDestType.subtype=MEDIASUBTYPE_RGB24; | |
286 break; | |
287 case 32: | |
288 m_sDestType.subtype=MEDIASUBTYPE_RGB32; | |
289 break; | |
290 default: | |
291 break; | |
292 } | |
293 m_obh.setBits(bits); | |
294 // .biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8)); | |
295 } | |
296 else | |
297 { | |
298 m_obh.setSpace(csp,bits); | |
299 switch(csp) | |
300 { | |
301 case fccYUY2: | |
302 m_sDestType.subtype=MEDIASUBTYPE_YUY2; | |
303 printf("DShow: using YUY2 colorspace\n"); | |
304 break; | |
305 case fccYV12: | |
306 m_sDestType.subtype=MEDIASUBTYPE_YV12; | |
307 printf("DShow: using YV12 colorspace\n"); | |
308 break; | |
309 case fccIYUV: | |
310 m_sDestType.subtype=MEDIASUBTYPE_IYUV; | |
311 printf("DShow: using IYUV colorspace\n"); | |
312 break; | |
313 case fccUYVY: | |
314 m_sDestType.subtype=MEDIASUBTYPE_UYVY; | |
315 printf("DShow: using UYVY colorspace\n"); | |
316 break; | |
317 case fccYVYU: | |
318 m_sDestType.subtype=MEDIASUBTYPE_YVYU; | |
319 printf("DShow: using YVYU colorspace\n"); | |
320 break; | |
321 } | |
322 } | |
323 | |
324 m_sDestType.lSampleSize=m_obh.biSizeImage; | |
325 memcpy(&(m_sVhdr2->bmiHeader), &m_obh, sizeof(m_obh)); | |
326 m_sVhdr2->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); | |
327 if(m_sVhdr2->bmiHeader.biCompression==3) | |
328 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER)+12; | |
329 else | |
330 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER); | |
331 | |
332 result=dsf->m_pOutputPin->vt->QueryAccept(dsf->m_pOutputPin, &m_sDestType); | |
333 | |
334 if(result!=0) | |
335 { | |
336 if(csp) | |
337 cerr<<"Warning: unsupported color space"<<endl; | |
338 else | |
339 cerr<<"Warning: unsupported bit depth"<<endl; | |
340 | |
341 m_sDestType.lSampleSize=m_decoder.biSizeImage; | |
342 memcpy(&(m_sVhdr2->bmiHeader), &m_decoder, sizeof(m_decoder)); | |
343 m_sVhdr2->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); | |
344 if(m_sVhdr2->bmiHeader.biCompression==3) | |
345 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER)+12; | |
346 else | |
347 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER); | |
348 return 1; | |
349 } | |
350 | |
351 m_decoder=m_obh; | |
352 // m_obh=temp; | |
353 // if(csp) | |
354 // m_obh.biBitCount=BitmapInfo::BitCount(csp); | |
355 m_bh->biBitCount=bits; | |
356 if(dsf->m_iState>0) | |
357 { | |
358 int old_state=dsf->m_iState; | |
359 if(dsf->m_iState==2) DS_VideoDecoder_Stop(); | |
360 dsf->m_pInputPin->vt->Disconnect(dsf->m_pInputPin); | |
361 dsf->m_pOutputPin->vt->Disconnect(dsf->m_pOutputPin); | |
362 dsf->m_pOurOutput->SetNewFormat(m_sDestType); | |
363 result=dsf->m_pInputPin->vt->ReceiveConnection(dsf->m_pInputPin, dsf->m_pOurInput, &m_sOurType); | |
364 if(result) | |
365 { | |
366 cerr<<"Error reconnecting input pin "<<hex<<result<<dec<<endl; | |
367 return -1; | |
368 } | |
369 result=dsf->m_pOutputPin->vt->ReceiveConnection(dsf->m_pOutputPin, | |
370 dsf->m_pOurOutput, &m_sDestType); | |
371 if(result) | |
372 { | |
373 cerr<<"Error reconnecting output pin "<<hex<<result<<dec<<endl; | |
374 return -1; | |
375 } | |
376 if(old_state==2) DS_VideoDecoder_Start(); | |
377 } | |
378 return 0; | |
379 } | 71 } |
380 | 72 |
381 | |
382 extern "C" int DS_SetValue_DivX(char* name, int value){ | 73 extern "C" int DS_SetValue_DivX(char* name, int value){ |
383 int temp; | 74 DS_VideoDecoder* dec=(DS_VideoDecoder*) _handle; |
384 if(dsf->m_iState!=2) return VFW_E_NOT_RUNNING; | 75 return (int) dec->SetValue(name,value); |
385 // brightness 87 | |
386 // contrast 74 | |
387 // hue 23 | |
388 // saturation 20 | |
389 // post process mode 0 | |
390 // get1 0x01 | |
391 // get2 10 | |
392 // get3=set2 86 | |
393 // get4=set3 73 | |
394 // get5=set4 19 | |
395 // get6=set5 23 | |
396 // printf("DivX setting: %s = %d\n",name,value); | |
397 | |
398 IHidden* hidden=(IHidden*)((int)dsf->m_pFilter+0xb8); | |
399 if(strcmp(name, "Brightness")==0) | |
400 return hidden->vt->SetSmth2(hidden, value, 0); | |
401 if(strcmp(name, "Contrast")==0) | |
402 return hidden->vt->SetSmth3(hidden, value, 0); | |
403 if(strcmp(name, "Hue")==0) | |
404 return hidden->vt->SetSmth5(hidden, value, 0); | |
405 if(strcmp(name, "Saturation")==0) | |
406 return hidden->vt->SetSmth4(hidden, value, 0); | |
407 if(strcmp(name, "Quality")==0) | |
408 return hidden->vt->SetSmth(hidden, value, 0); | |
409 | |
410 printf("Invalid setting!\n"); | |
411 return -200; | |
412 } | 76 } |
413 | 77 |
414 extern "C" int DS_SetAttr_DivX(char* attribute, int value){ | 78 extern "C" int DS_SetAttr_DivX(char* attribute, int value){ |
415 int result, status, newkey, count; | 79 int result, status, newkey, count; |
416 if(strcmp(attribute, "Quality")==0){ | 80 if(strcmp(attribute, "Quality")==0){ |