Mercurial > mplayer.hg
annotate loader/dshow/DS_VideoDec.c @ 1273:17c13bef14f4
-fsmode
author | gabucino |
---|---|
date | Wed, 04 Jul 2001 16:32:38 +0000 |
parents | 53f5b3b991f5 |
children | bd6ea9bd3f80 |
rev | line source |
---|---|
169 | 1 /******************************************************** |
2 | |
3 DirectShow Video decoder implementation | |
4 Copyright 2000 Eugene Kuznetsov (divx@euro.ru) | |
5 Converted C++ --> C :) by A'rpi/ESP-team | |
6 | |
7 *********************************************************/ | |
8 | |
9 //#include <config.h> | |
10 | |
11 //#include "DS_VideoDecoder.h" | |
1073
1485ab9af8a1
ehh. removed duplicated namspace 'std'... and removed include string.h, unneeded for c++
arpi_esp
parents:
1063
diff
changeset
|
12 //#include <string.h> |
1082 | 13 using namespace std; |
169 | 14 #include <stdlib.h> |
15 #include <except.h> | |
16 #define __MODULE__ "DirectShow_VideoDecoder" | |
17 | |
1063 | 18 |
169 | 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> | |
27 #include <fcntl.h> | |
28 #include <strstream> | |
29 #include <dlfcn.h> | |
30 #include <sys/types.h> | |
31 #include <sys/mman.h> | |
32 | |
173 | 33 #include <registry.h> |
34 #include <wine/winreg.h> | |
35 | |
169 | 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 | |
45 #include "DS_VideoDec.h" | |
46 | |
173 | 47 |
169 | 48 extern "C" char* def_path; |
49 | |
50 static char** m_destptr=0; | |
51 | |
52 static DS_Filter* dsf=0; | |
53 | |
54 static AM_MEDIA_TYPE m_sOurType, m_sDestType; | |
55 static VIDEOINFOHEADER m_sVhdr; | |
56 static VIDEOINFOHEADER *m_sVhdr2; | |
57 static void* m_pCust; | |
58 | |
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 | |
713 | 83 memset(&m_sVhdr, 0, sizeof(m_sVhdr)); |
169 | 84 m_sVhdr.bmiHeader=m_bh; |
85 m_sVhdr.rcSource.left=m_sVhdr.rcSource.top=0; | |
86 m_sVhdr.rcSource.right=m_sVhdr.bmiHeader.biWidth; | |
87 m_sVhdr.rcSource.bottom=m_sVhdr.bmiHeader.biHeight; | |
88 m_sVhdr.rcTarget=m_sVhdr.rcSource; | |
89 m_sOurType.majortype=MEDIATYPE_Video; | |
90 | |
91 m_sOurType.subtype=MEDIATYPE_Video; | |
92 m_sOurType.subtype.f1=m_sVhdr.bmiHeader.biCompression; | |
93 m_sOurType.formattype=FORMAT_VideoInfo; | |
94 m_sOurType.bFixedSizeSamples=false; | |
95 m_sOurType.bTemporalCompression=true; | |
96 m_sOurType.pUnk=0; | |
713 | 97 m_sOurType.cbFormat=sizeof(m_sVhdr); |
169 | 98 m_sOurType.pbFormat=(char*)&m_sVhdr; |
99 | |
100 m_sVhdr2=(VIDEOINFOHEADER*)(new char[sizeof(VIDEOINFOHEADER)+12]); | |
101 *m_sVhdr2=m_sVhdr; | |
102 m_sVhdr2->bmiHeader.biCompression=0; | |
103 m_sVhdr2->bmiHeader.biBitCount=24; | |
104 | |
713 | 105 memset(&m_sDestType, 0, sizeof(m_sDestType)); |
169 | 106 m_sDestType.majortype=MEDIATYPE_Video; |
107 m_sDestType.subtype=MEDIASUBTYPE_RGB24; | |
108 m_sDestType.formattype=FORMAT_VideoInfo; | |
109 m_sDestType.bFixedSizeSamples=true; | |
110 m_sDestType.bTemporalCompression=false; | |
111 m_sDestType.lSampleSize=abs(m_sVhdr2->bmiHeader.biWidth*m_sVhdr2->bmiHeader.biHeight* | |
112 ((m_sVhdr2->bmiHeader.biBitCount+7)/8)); | |
113 m_sVhdr2->bmiHeader.biSizeImage=m_sDestType.lSampleSize; | |
114 m_sDestType.pUnk=0; | |
115 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER); | |
116 m_sDestType.pbFormat=(char*)m_sVhdr2; | |
117 | |
118 m_obh=m_bh; | |
119 m_obh.setBits(24); | |
120 | |
121 HRESULT result; | |
122 | |
713 | 123 dsf=new DS_Filter(); |
124 dsf->Create(dllname, guid, &m_sOurType, &m_sDestType); | |
125 | |
169 | 126 if(!flip) |
127 { | |
128 m_sVhdr2->bmiHeader.biHeight*=-1; | |
129 m_obh.biHeight*=-1; | |
713 | 130 result=dsf->m_pOutputPin->vt->QueryAccept(dsf->m_pOutputPin, &m_sDestType); |
131 if(result){ | |
132 printf("DShow: Decoder does not support upside-down frames"); | |
133 m_obh.biHeight*=-1; | |
134 } | |
169 | 135 } |
136 | |
468 | 137 #if 0 |
169 | 138 m_sVhdr2->bmiHeader.biBitCount=16; |
139 m_sVhdr2->bmiHeader.biCompression=fccYUY2; | |
140 m_sDestType.subtype=MEDIASUBTYPE_YUY2; | |
141 result=dsf->m_pOutputPin->vt->QueryAccept(dsf->m_pOutputPin, &m_sDestType); | |
142 // if(!result) caps=(CAPS)(caps | CAP_YUY2); | |
468 | 143 #endif |
169 | 144 |
145 m_sVhdr2->bmiHeader.biBitCount=24; | |
146 m_sVhdr2->bmiHeader.biCompression=0; | |
147 m_sDestType.subtype=MEDIASUBTYPE_RGB24; | |
148 m_decoder=m_obh; | |
149 //qual = 0-1; | |
150 } | |
151 catch(FatalError& error) | |
152 { | |
153 delete[] m_sVhdr2; | |
154 return 1; | |
155 } | |
156 return 0; | |
157 } | |
158 | |
159 extern "C" void DS_VideoDecoder_Start(){ | |
160 if(dsf->m_iState!=1) return; | |
161 dsf->Start(); | |
162 | |
163 ALLOCATOR_PROPERTIES props, props1; | |
164 props.cBuffers=1; | |
165 props.cbBuffer=1024*1024; //m_sDestType.lSampleSize;//don't know how to do this correctly | |
166 props.cbAlign=props.cbPrefix=0; | |
167 dsf->m_pAll->vt->SetProperties(dsf->m_pAll, &props, &props1); | |
168 dsf->m_pAll->vt->Commit(dsf->m_pAll); | |
169 | |
170 // m_outFrame=new CImage(&m_decoder,(unsigned char *)malloc(m_sDestType.lSampleSize),false); | |
171 //m_outFrame=new CImage(&m_decoder, 0, false); | |
172 // printf("Datap %x\n",m_outFrame->getaddr()); | |
173 | |
174 | |
175 // dsf->m_pOurOutput->SetFramePointer((char **)m_outFrame->getaddr()); //!FIXME! | |
176 dsf->m_pOurOutput->SetFramePointer(m_destptr); //!FIXME! | |
177 | |
178 // filling = realtime; | |
179 | |
180 dsf->m_iState=2; | |
181 return; | |
182 } | |
183 | |
184 extern "C" void DS_VideoDecoder_Stop(){ | |
185 if(dsf->m_iState!=2) return; | |
186 dsf->Stop(); | |
713 | 187 // dsf->m_pOurOutput->SetFramePointer(0); |
169 | 188 // free(m_outFrame->data()); |
189 //m_outFrame->release();//just in case | |
190 //m_outFrame=0; | |
191 // FlushCache(); | |
192 dsf->m_iState=1; | |
193 return; | |
194 } | |
195 | |
196 extern "C" void DS_VideoDecoder_Restart(){ | |
197 if(dsf->m_iState!=2) return; | |
198 | |
199 dsf->Stop(); | |
200 dsf->Start(); | |
201 | |
202 ALLOCATOR_PROPERTIES props, props1; | |
203 props.cBuffers=1; | |
204 props.cbBuffer=m_sDestType.lSampleSize;//don't know how to do this correctly | |
205 props.cbAlign=props.cbPrefix=0; | |
206 dsf->m_pAll->vt->SetProperties(dsf->m_pAll, &props, &props1); | |
207 dsf->m_pAll->vt->Commit(dsf->m_pAll); | |
208 } | |
209 | |
210 extern "C" void DS_VideoDecoder_Close(){ | |
211 if(dsf->m_iState==0) return; | |
212 if(dsf->m_iState==2) DS_VideoDecoder_Stop(); | |
213 delete[] m_sVhdr2; | |
214 // delete m_outFrame; | |
215 } | |
216 | |
217 extern "C" int DS_VideoDecoder_DecodeFrame(char* src, int size, int is_keyframe, int render){ | |
218 | |
219 if(!size)return 0; | |
220 | |
221 m_bh.biSizeImage=size; | |
222 | |
223 IMediaSample* sample=0; | |
173 | 224 //printf("GetBuffer... (m_pAll=%X) ",dsf->m_pAll);fflush(stdout); |
169 | 225 dsf->m_pAll->vt->GetBuffer(dsf->m_pAll, &sample, 0, 0, 0); |
173 | 226 //printf("OK!\n"); |
169 | 227 if(!sample) |
228 { | |
229 Debug cerr<<"ERROR: null sample"<<endl; | |
230 return -1; | |
231 } | |
232 char* ptr; | |
173 | 233 //printf("GetPtr...");fflush(stdout); |
169 | 234 sample->vt->GetPointer(sample, (BYTE **)&ptr); |
173 | 235 //printf("OK!\n"); |
169 | 236 memcpy(ptr, src, size); |
173 | 237 //printf("memcpy OK!\n"); |
169 | 238 sample->vt->SetActualDataLength(sample, size); |
173 | 239 //printf("SetActualDataLength OK!\n"); |
169 | 240 sample->vt->SetSyncPoint(sample, is_keyframe); |
173 | 241 //printf("SetSyncPoint OK!\n"); |
169 | 242 sample->vt->SetPreroll(sample, !render); |
243 // sample->vt->SetMediaType(sample, &m_sOurType); | |
244 int result=dsf->m_pImp->vt->Receive(dsf->m_pImp, sample); | |
245 if(result) | |
173 | 246 printf("Error putting data into input pin %x\n", result); |
169 | 247 |
248 sample->vt->Release((IUnknown*)sample); | |
249 | |
250 return 0; | |
251 } | |
252 | |
253 extern "C" int DS_VideoDecoder_SetDestFmt(int bits, int csp){ | |
254 if(dsf->m_iState==0) return -1; | |
255 // if(!CImage::supported(csp, bits)) return -1; | |
256 HRESULT result; | |
257 // BitmapInfo temp=m_obh; | |
258 if(csp==0) | |
259 { | |
260 switch(bits) | |
261 { | |
262 case 15: | |
263 m_sDestType.subtype=MEDIASUBTYPE_RGB555; | |
264 break; | |
265 case 16: | |
266 m_sDestType.subtype=MEDIASUBTYPE_RGB565; | |
267 break; | |
268 case 24: | |
269 m_sDestType.subtype=MEDIASUBTYPE_RGB24; | |
270 break; | |
271 case 32: | |
272 m_sDestType.subtype=MEDIASUBTYPE_RGB32; | |
273 break; | |
274 default: | |
275 break; | |
276 } | |
277 m_obh.setBits(bits); | |
278 // .biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8)); | |
279 } | |
280 else | |
281 { | |
468 | 282 m_obh.setSpace(csp,bits); |
169 | 283 switch(csp) |
284 { | |
285 case fccYUY2: | |
286 m_sDestType.subtype=MEDIASUBTYPE_YUY2; | |
468 | 287 printf("DShow: using YUY2 colorspace\n"); |
169 | 288 break; |
289 case fccYV12: | |
290 m_sDestType.subtype=MEDIASUBTYPE_YV12; | |
468 | 291 printf("DShow: using YV12 colorspace\n"); |
169 | 292 break; |
293 case fccIYUV: | |
294 m_sDestType.subtype=MEDIASUBTYPE_IYUV; | |
468 | 295 printf("DShow: using IYUV colorspace\n"); |
169 | 296 break; |
297 case fccUYVY: | |
298 m_sDestType.subtype=MEDIASUBTYPE_UYVY; | |
468 | 299 printf("DShow: using UYVY colorspace\n"); |
169 | 300 break; |
301 case fccYVYU: | |
302 m_sDestType.subtype=MEDIASUBTYPE_YVYU; | |
468 | 303 printf("DShow: using YVYU colorspace\n"); |
169 | 304 break; |
305 } | |
306 } | |
307 | |
308 m_sDestType.lSampleSize=m_obh.biSizeImage; | |
309 memcpy(&(m_sVhdr2->bmiHeader), &m_obh, sizeof(m_obh)); | |
310 m_sVhdr2->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); | |
311 if(m_sVhdr2->bmiHeader.biCompression==3) | |
312 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER)+12; | |
313 else | |
314 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER); | |
315 | |
316 result=dsf->m_pOutputPin->vt->QueryAccept(dsf->m_pOutputPin, &m_sDestType); | |
317 | |
318 if(result!=0) | |
319 { | |
320 if(csp) | |
321 cerr<<"Warning: unsupported color space"<<endl; | |
322 else | |
323 cerr<<"Warning: unsupported bit depth"<<endl; | |
324 | |
325 m_sDestType.lSampleSize=m_decoder.biSizeImage; | |
326 memcpy(&(m_sVhdr2->bmiHeader), &m_decoder, sizeof(m_decoder)); | |
327 m_sVhdr2->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); | |
328 if(m_sVhdr2->bmiHeader.biCompression==3) | |
329 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER)+12; | |
330 else | |
331 m_sDestType.cbFormat=sizeof(VIDEOINFOHEADER); | |
332 return 1; | |
333 } | |
334 | |
335 m_decoder=m_obh; | |
336 // m_obh=temp; | |
337 // if(csp) | |
338 // m_obh.biBitCount=BitmapInfo::BitCount(csp); | |
339 m_bh.biBitCount=bits; | |
340 if(dsf->m_iState>0) | |
341 { | |
342 int old_state=dsf->m_iState; | |
343 if(dsf->m_iState==2) DS_VideoDecoder_Stop(); | |
344 dsf->m_pInputPin->vt->Disconnect(dsf->m_pInputPin); | |
345 dsf->m_pOutputPin->vt->Disconnect(dsf->m_pOutputPin); | |
346 dsf->m_pOurOutput->SetNewFormat(m_sDestType); | |
347 result=dsf->m_pInputPin->vt->ReceiveConnection(dsf->m_pInputPin, dsf->m_pOurInput, &m_sOurType); | |
348 if(result) | |
349 { | |
350 cerr<<"Error reconnecting input pin "<<hex<<result<<dec<<endl; | |
351 return -1; | |
352 } | |
353 result=dsf->m_pOutputPin->vt->ReceiveConnection(dsf->m_pOutputPin, | |
354 dsf->m_pOurOutput, &m_sDestType); | |
355 if(result) | |
356 { | |
357 cerr<<"Error reconnecting output pin "<<hex<<result<<dec<<endl; | |
358 return -1; | |
359 } | |
360 if(old_state==2) DS_VideoDecoder_Start(); | |
361 } | |
362 return 0; | |
363 } | |
364 | |
365 | |
366 extern "C" int DS_SetValue_DivX(char* name, int value){ | |
367 int temp; | |
368 if(dsf->m_iState!=2) return VFW_E_NOT_RUNNING; | |
369 // brightness 87 | |
370 // contrast 74 | |
371 // hue 23 | |
372 // saturation 20 | |
373 // post process mode 0 | |
374 // get1 0x01 | |
375 // get2 10 | |
376 // get3=set2 86 | |
377 // get4=set3 73 | |
378 // get5=set4 19 | |
379 // get6=set5 23 | |
380 printf("DivX setting: %s = %d\n",name,value); | |
381 | |
382 IHidden* hidden=(IHidden*)((int)dsf->m_pFilter+0xb8); | |
383 if(strcmp(name, "Brightness")==0) | |
384 return hidden->vt->SetSmth2(hidden, value, 0); | |
385 if(strcmp(name, "Contrast")==0) | |
386 return hidden->vt->SetSmth3(hidden, value, 0); | |
387 if(strcmp(name, "Hue")==0) | |
388 return hidden->vt->SetSmth5(hidden, value, 0); | |
389 if(strcmp(name, "Saturation")==0) | |
390 return hidden->vt->SetSmth4(hidden, value, 0); | |
391 if(strcmp(name, "Quality")==0) | |
392 return hidden->vt->SetSmth(hidden, value, 0); | |
393 | |
394 printf("Invalid setting!\n"); | |
395 return -200; | |
396 } | |
397 | |
173 | 398 extern "C" int DS_SetAttr_DivX(char* attribute, int value){ |
399 int result, status, newkey, count; | |
400 if(strcmp(attribute, "Quality")==0){ | |
401 char* keyname="SOFTWARE\\Microsoft\\Scrunch"; | |
402 result=RegCreateKeyExA(HKEY_CURRENT_USER, keyname, 0, 0, 0, 0, 0, &newkey, &status); | |
403 if(result!=0) | |
404 { | |
405 printf("VideoDecoder::SetExtAttr: registry failure\n"); | |
406 return -1; | |
407 } | |
408 result=RegSetValueExA(newkey, "Current Post Process Mode", 0, REG_DWORD, &value, 4); | |
409 if(result!=0) | |
410 { | |
411 printf("VideoDecoder::SetExtAttr: error writing value\n"); | |
412 return -1; | |
413 } | |
414 value=-1; | |
415 result=RegSetValueExA(newkey, "Force Post Process Mode", 0, REG_DWORD, &value, 4); | |
416 if(result!=0) | |
417 { | |
418 printf("VideoDecoder::SetExtAttr: error writing value\n"); | |
419 return -1; | |
420 } | |
421 RegCloseKey(newkey); | |
422 return 0; | |
423 } | |
169 | 424 |
173 | 425 if( |
426 (strcmp(attribute, "Saturation")==0) || | |
427 (strcmp(attribute, "Hue")==0) || | |
428 (strcmp(attribute, "Contrast")==0) || | |
429 (strcmp(attribute, "Brightness")==0) | |
430 ) | |
431 { | |
432 char* keyname="SOFTWARE\\Microsoft\\Scrunch\\Video"; | |
433 result=RegCreateKeyExA(HKEY_CURRENT_USER, keyname, 0, 0, 0, 0, 0, &newkey, &status); | |
434 if(result!=0) | |
435 { | |
436 printf("VideoDecoder::SetExtAttr: registry failure\n"); | |
437 return -1; | |
438 } | |
439 result=RegSetValueExA(newkey, attribute, 0, REG_DWORD, &value, 4); | |
440 if(result!=0) | |
441 { | |
442 printf("VideoDecoder::SetExtAttr: error writing value\n"); | |
443 return -1; | |
444 } | |
445 RegCloseKey(newkey); | |
446 return 0; | |
447 } | |
448 | |
449 printf("Unknown attribute!\n"); | |
450 return -200; | |
451 } | |
452 |