Mercurial > mplayer.hg
comparison loader/dshow/DS_VideoDecoder.c @ 1545:da26060c81ef
big avifile sync - from now we have common code
author | arpi |
---|---|
date | Thu, 16 Aug 2001 00:50:02 +0000 |
parents | |
children | 076c27342828 |
comparison
equal
deleted
inserted
replaced
1544:558c1b03b8d0 | 1545:da26060c81ef |
---|---|
1 /******************************************************** | |
2 | |
3 DirectShow Video decoder implementation | |
4 Copyright 2000 Eugene Kuznetsov (divx@euro.ru) | |
5 | |
6 *********************************************************/ | |
7 | |
8 #include "guids.h" | |
9 #include "interfaces.h" | |
10 | |
11 #include "DS_VideoDecoder.h" | |
12 #include <wine/winerror.h> | |
13 #include <libwin32.h> | |
14 //#include <cpuinfo.h> | |
15 | |
16 #include <unistd.h> | |
17 #include <fcntl.h> | |
18 #include <errno.h> | |
19 #include <sys/types.h> | |
20 #include <sys/mman.h> | |
21 #include <cstdio> | |
22 #include <iostream> | |
23 #include <strstream> | |
24 | |
25 #define __MODULE__ "DirectShow_VideoDecoder" | |
26 | |
27 extern "C" char* def_path; | |
28 extern "C" void setup_FS_Segment(); | |
29 | |
30 using namespace std; | |
31 | |
32 DS_VideoDecoder::DS_VideoDecoder(const CodecInfo& info, const BITMAPINFOHEADER& format, int flip) | |
33 :IVideoDecoder(info, format) | |
34 { | |
35 m_sVhdr2 = 0; | |
36 m_iLastQuality = -1; | |
37 //memset(&m_obh, 0, sizeof(m_obh)); | |
38 //m_obh.biSize = sizeof(m_obh); | |
39 try | |
40 { | |
41 m_pDS_Filter = new DS_Filter(); | |
42 | |
43 unsigned bihs = (format.biSize < (int) sizeof(BITMAPINFOHEADER)) ? | |
44 sizeof(BITMAPINFOHEADER) : format.biSize; | |
45 bihs = sizeof(VIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER) + bihs; | |
46 | |
47 m_sVhdr = (VIDEOINFOHEADER*) new char[bihs]; | |
48 memset(m_sVhdr, 0, bihs); | |
49 memcpy(&m_sVhdr->bmiHeader, m_bh, m_bh->biSize); | |
50 m_sVhdr->rcSource.left = m_sVhdr->rcSource.top = 0; | |
51 m_sVhdr->rcSource.right = m_sVhdr->bmiHeader.biWidth; | |
52 m_sVhdr->rcSource.bottom = m_sVhdr->bmiHeader.biHeight; | |
53 m_sVhdr->rcTarget = m_sVhdr->rcSource; | |
54 | |
55 m_sOurType.majortype = MEDIATYPE_Video; | |
56 m_sOurType.subtype = MEDIATYPE_Video; | |
57 m_sOurType.subtype.f1 = m_sVhdr->bmiHeader.biCompression; | |
58 m_sOurType.formattype = FORMAT_VideoInfo; | |
59 m_sOurType.bFixedSizeSamples = false; | |
60 m_sOurType.bTemporalCompression = true; | |
61 m_sOurType.pUnk = 0; | |
62 m_sOurType.cbFormat = bihs; | |
63 m_sOurType.pbFormat = (char*)m_sVhdr; | |
64 | |
65 m_sVhdr2 = (VIDEOINFOHEADER*)(new char[sizeof(VIDEOINFOHEADER)+12]); | |
66 memcpy(m_sVhdr2, m_sVhdr, sizeof(VIDEOINFOHEADER)+12); | |
67 m_sVhdr2->bmiHeader.biCompression = 0; | |
68 m_sVhdr2->bmiHeader.biBitCount = 24; | |
69 | |
70 memset(&m_sDestType, 0, sizeof(m_sDestType)); | |
71 m_sDestType.majortype = MEDIATYPE_Video; | |
72 m_sDestType.subtype = MEDIASUBTYPE_RGB24; | |
73 m_sDestType.formattype = FORMAT_VideoInfo; | |
74 m_sDestType.bFixedSizeSamples = true; | |
75 m_sDestType.bTemporalCompression = false; | |
76 m_sDestType.lSampleSize = abs(m_sVhdr2->bmiHeader.biWidth*m_sVhdr2->bmiHeader.biHeight | |
77 * ((m_sVhdr2->bmiHeader.biBitCount + 7) / 8)); | |
78 m_sVhdr2->bmiHeader.biSizeImage = m_sDestType.lSampleSize; | |
79 m_sDestType.pUnk = 0; | |
80 m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); | |
81 m_sDestType.pbFormat = (char*)m_sVhdr2; | |
82 memcpy(&m_obh, m_bh, sizeof(m_obh)); | |
83 m_obh.SetBits(24); | |
84 | |
85 HRESULT result; | |
86 | |
87 m_pDS_Filter->Create(info.dll.c_str(), &info.guid, &m_sOurType, &m_sDestType); | |
88 | |
89 if (!flip) | |
90 { | |
91 m_sVhdr2->bmiHeader.biHeight *= -1; | |
92 m_obh.biHeight *= -1; | |
93 result = m_pDS_Filter->m_pOutputPin->vt->QueryAccept(m_pDS_Filter->m_pOutputPin, &m_sDestType); | |
94 if (result) | |
95 { | |
96 cerr << "Decoder does not support upside-down frames" << endl; | |
97 m_sVhdr2->bmiHeader.biHeight *= -1; | |
98 m_obh.biHeight *= -1; | |
99 } | |
100 } | |
101 | |
102 m_decoder = m_obh; | |
103 | |
104 switch (m_bh->biCompression) | |
105 { | |
106 case fccDIV3: | |
107 case fccDIV4: | |
108 case fccDIV5: | |
109 case fccMP42: | |
110 case fccWMV2: | |
111 //YV12 seems to be broken for DivX :-) codec | |
112 case fccIV50: | |
113 //produces incorrect picture | |
114 //m_Caps = (CAPS) (m_Caps & ~CAP_YV12); | |
115 m_Caps = CAP_YUY2; // | CAP_I420; | |
116 break; | |
117 default: | |
118 struct ct { | |
119 unsigned int bits; | |
120 fourcc_t fcc; | |
121 GUID subtype; | |
122 CAPS cap; | |
123 } check[] = { | |
124 {16, fccYUY2, MEDIASUBTYPE_YUY2, CAP_YUY2}, | |
125 {12, fccIYUV, MEDIASUBTYPE_IYUV, CAP_IYUV}, | |
126 {16, fccUYVY, MEDIASUBTYPE_UYVY, CAP_UYVY}, | |
127 {12, fccYV12, MEDIASUBTYPE_YV12, CAP_YV12}, | |
128 {16, fccYV12, MEDIASUBTYPE_YV12, CAP_YV12}, | |
129 {16, fccYVYU, MEDIASUBTYPE_YVYU, CAP_YVYU}, | |
130 //{12, fccI420, MEDIASUBTYPE_I420, CAP_I420}, | |
131 {0}, | |
132 }; | |
133 | |
134 m_Caps = CAP_NONE; | |
135 | |
136 for (ct* c = check; c->bits; c++) | |
137 { | |
138 m_sVhdr2->bmiHeader.biBitCount = c->bits; | |
139 m_sVhdr2->bmiHeader.biCompression = c->fcc; | |
140 m_sDestType.subtype = c->subtype; | |
141 result = m_pDS_Filter->m_pOutputPin->vt->QueryAccept(m_pDS_Filter->m_pOutputPin, &m_sDestType); | |
142 if (!result) | |
143 m_Caps = (CAPS)(m_Caps | c->cap); | |
144 } | |
145 } | |
146 | |
147 if (m_Caps != CAP_NONE) | |
148 cout << "Decoder is capable of YUV output ( flags 0x"<<hex<<(int)m_Caps<<dec<<" )"<<endl; | |
149 | |
150 m_sVhdr2->bmiHeader.biBitCount = 24; | |
151 m_sVhdr2->bmiHeader.biCompression = 0; | |
152 m_sDestType.subtype = MEDIASUBTYPE_RGB24; | |
153 | |
154 m_bIsDivX = ((info.dll == string("divxcvki.ax")) | |
155 || (info.dll == string("divx_c32.ax")) | |
156 || (info.dll == string("wmvds32.ax")) | |
157 || (info.dll == string("wmv8ds32.ax"))); | |
158 } | |
159 catch (FatalError& error) | |
160 { | |
161 delete[] m_sVhdr2; | |
162 delete m_pDS_Filter; | |
163 throw; | |
164 } | |
165 } | |
166 | |
167 DS_VideoDecoder::~DS_VideoDecoder() | |
168 { | |
169 Stop(); | |
170 delete[] m_sVhdr2; | |
171 delete m_pDS_Filter; | |
172 } | |
173 | |
174 void DS_VideoDecoder::StartInternal() | |
175 { | |
176 //cout << "DSSTART" << endl; | |
177 m_pDS_Filter->Start(); | |
178 ALLOCATOR_PROPERTIES props, props1; | |
179 props.cBuffers = 1; | |
180 props.cbBuffer = m_sDestType.lSampleSize; | |
181 //don't know how to do this correctly | |
182 props.cbAlign = props.cbPrefix = 0; | |
183 m_pDS_Filter->m_pAll->vt->SetProperties(m_pDS_Filter->m_pAll, &props, &props1); | |
184 m_pDS_Filter->m_pAll->vt->Commit(m_pDS_Filter->m_pAll); | |
185 } | |
186 | |
187 void DS_VideoDecoder::StopInternal() | |
188 { | |
189 //cout << "DSSTOP" << endl; | |
190 m_pDS_Filter->Stop(); | |
191 //??? why was this here ??? m_pOurOutput->SetFramePointer(0); | |
192 } | |
193 | |
194 int DS_VideoDecoder::DecodeInternal(void* src, size_t size, int is_keyframe, CImage* pImage) | |
195 { | |
196 IMediaSample* sample = 0; | |
197 | |
198 m_pDS_Filter->m_pAll->vt->GetBuffer(m_pDS_Filter->m_pAll, &sample, 0, 0, 0); | |
199 | |
200 if (!sample) | |
201 { | |
202 Debug cerr << "ERROR: null sample" << endl; | |
203 return -1; | |
204 } | |
205 | |
206 //cout << "DECODE " << (void*) pImage << " d: " << (void*) pImage->Data() << endl; | |
207 if (pImage) | |
208 { | |
209 if (!(pImage->Data())) | |
210 { | |
211 Debug cout << "no m_outFrame??" << endl; | |
212 } | |
213 else | |
214 m_pDS_Filter->m_pOurOutput->SetPointer2((char*)pImage->Data()); | |
215 } | |
216 | |
217 char* ptr; | |
218 sample->vt->GetPointer(sample, (BYTE **)&ptr); | |
219 memcpy(ptr, src, size); | |
220 sample->vt->SetActualDataLength(sample, size); | |
221 sample->vt->SetSyncPoint(sample, is_keyframe); | |
222 sample->vt->SetPreroll(sample, pImage ? 0 : 1); | |
223 // sample->vt->SetMediaType(sample, &m_sOurType); | |
224 | |
225 // FIXME: - crashing with YV12 at this place decoder will crash | |
226 // while doing this call | |
227 // %FS register was not setup for calling into win32 dll. Are all | |
228 // crashes inside ...->Receive() fixed now? | |
229 // | |
230 // nope - but this is surely helpfull - I'll try some more experiments | |
231 setup_FS_Segment(); | |
232 #if 0 | |
233 if (!m_pDS_Filter || !m_pDS_Filter->m_pImp | |
234 || !m_pDS_Filter->m_pImp->vt | |
235 || !m_pDS_Filter->m_pImp->vt->Receive) | |
236 printf("DecodeInternal ERROR???\n"); | |
237 #endif | |
238 int result = m_pDS_Filter->m_pImp->vt->Receive(m_pDS_Filter->m_pImp, sample); | |
239 if (result) | |
240 { | |
241 Debug printf("DS_VideoDecoder::DecodeInternal() error putting data into input pin %x\n", result); | |
242 } | |
243 | |
244 sample->vt->Release((IUnknown*)sample); | |
245 | |
246 if (m_bIsDivX) | |
247 { | |
248 int q; | |
249 IHidden* hidden=(IHidden*)((int)m_pDS_Filter->m_pFilter + 0xb8); | |
250 // always check for actual value | |
251 // this seems to be the only way to know the actual value | |
252 hidden->vt->GetSmth2(hidden, &m_iLastQuality); | |
253 if (m_iLastQuality > 9) | |
254 m_iLastQuality -= 10; | |
255 | |
256 if (m_iLastQuality < 0) | |
257 m_iLastQuality = 0; | |
258 else if (m_iLastQuality > 4) | |
259 m_iLastQuality = 4; | |
260 | |
261 //cout << " Qual: " << m_iLastQuality << endl; | |
262 m_fQuality = m_iLastQuality / 4.0; | |
263 } | |
264 | |
265 // FIXME: last_quality currently works only for DivX movies | |
266 // more general approach is needed here | |
267 // cout << "Q: " << m_iLastQuality << " rt: " << m_Mode << " dp: " << decpos << endl; | |
268 // also accesing vbuf doesn't look very nice at this place | |
269 // FIXME later - do it as a virtual method | |
270 | |
271 if (m_Mode == IVideoDecoder::REALTIME_QUALITY_AUTO) | |
272 { | |
273 // adjust Quality - depends on how many cached frames we have | |
274 int buffered = m_iDecpos - m_iPlaypos; | |
275 | |
276 if (m_bIsDivX) | |
277 { | |
278 //cout << "qual " << q << " " << buffered << endl; | |
279 if (buffered < (m_iLastQuality * 2 + QMARKLO - 1) | |
280 || buffered > ((m_iLastQuality + 1) * 2 + QMARKLO)) | |
281 { | |
282 // removed old code which was present here | |
283 // and replaced with this new uptodate one | |
284 | |
285 int to = (buffered - QMARKLO) / 2; | |
286 if (to < 0) | |
287 to = 0; | |
288 else if (to > 4) | |
289 to = 4; | |
290 if (m_iLastQuality != to) | |
291 { | |
292 IHidden* hidden=(IHidden*)((int)m_pDS_Filter->m_pFilter + 0xb8); | |
293 hidden->vt->SetSmth(hidden, to, 0); | |
294 #ifndef QUIET | |
295 //cout << "Switching quality " << m_iLastQuality << " -> " << to << " b:" << buffered << endl; | |
296 #endif | |
297 } | |
298 } | |
299 } | |
300 } | |
301 | |
302 | |
303 return 0; | |
304 } | |
305 | |
306 /* | |
307 * bits == 0 - leave unchanged | |
308 */ | |
309 int DS_VideoDecoder::SetDestFmt(int bits, fourcc_t csp) | |
310 { | |
311 if (!CImage::Supported(csp, bits)) | |
312 return -1; | |
313 | |
314 // BitmapInfo temp = m_obh; | |
315 if (bits != 0) | |
316 { | |
317 bool ok = true; | |
318 | |
319 switch (bits) | |
320 { | |
321 case 15: | |
322 m_sDestType.subtype = MEDIASUBTYPE_RGB555; | |
323 break; | |
324 case 16: | |
325 m_sDestType.subtype = MEDIASUBTYPE_RGB565; | |
326 break; | |
327 case 24: | |
328 m_sDestType.subtype = MEDIASUBTYPE_RGB24; | |
329 break; | |
330 case 32: | |
331 m_sDestType.subtype = MEDIASUBTYPE_RGB32; | |
332 break; | |
333 default: | |
334 ok = false; | |
335 break; | |
336 } | |
337 | |
338 if (ok) | |
339 m_obh.SetBits(bits); | |
340 //.biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8)); | |
341 } | |
342 | |
343 if (csp != 0) | |
344 { | |
345 bool ok = true; | |
346 switch (csp) | |
347 { | |
348 case fccYUY2: | |
349 m_sDestType.subtype = MEDIASUBTYPE_YUY2; | |
350 break; | |
351 case fccYV12: | |
352 m_sDestType.subtype = MEDIASUBTYPE_YV12; | |
353 break; | |
354 case fccIYUV: | |
355 m_sDestType.subtype = MEDIASUBTYPE_IYUV; | |
356 break; | |
357 case fccUYVY: | |
358 m_sDestType.subtype = MEDIASUBTYPE_UYVY; | |
359 break; | |
360 case fccYVYU: | |
361 m_sDestType.subtype = MEDIASUBTYPE_YVYU; | |
362 break; | |
363 default: | |
364 ok = false; | |
365 break; | |
366 } | |
367 | |
368 if (ok) | |
369 m_obh.SetSpace(csp); | |
370 } | |
371 m_sDestType.lSampleSize = m_obh.biSizeImage; | |
372 memcpy(&(m_sVhdr2->bmiHeader), &m_obh, sizeof(m_obh)); | |
373 m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
374 if (m_sVhdr2->bmiHeader.biCompression == 3) | |
375 m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; | |
376 else | |
377 m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); | |
378 | |
379 HRESULT result; | |
380 bool should_test=true; | |
381 switch(csp) | |
382 { | |
383 case fccYUY2: | |
384 if(!(m_Caps & CAP_YUY2)) | |
385 should_test=false; | |
386 break; | |
387 case fccYV12: | |
388 if(!(m_Caps & CAP_YV12)) | |
389 should_test=false; | |
390 break; | |
391 case fccIYUV: | |
392 if(!(m_Caps & CAP_IYUV)) | |
393 should_test=false; | |
394 break; | |
395 case fccUYVY: | |
396 if(!(m_Caps & CAP_UYVY)) | |
397 should_test=false; | |
398 break; | |
399 case fccYVYU: | |
400 if(!(m_Caps & CAP_YVYU)) | |
401 should_test=false; | |
402 break; | |
403 } | |
404 if(should_test) | |
405 result = m_pDS_Filter->m_pOutputPin->vt->QueryAccept(m_pDS_Filter->m_pOutputPin, &m_sDestType); | |
406 else | |
407 result = -1; | |
408 | |
409 if (result != 0) | |
410 { | |
411 if (csp) | |
412 cerr << "Warning: unsupported color space" << endl; | |
413 else | |
414 cerr << "Warning: unsupported bit depth" << endl; | |
415 | |
416 m_sDestType.lSampleSize = m_decoder.biSizeImage; | |
417 memcpy(&(m_sVhdr2->bmiHeader), &m_decoder, sizeof(m_decoder)); | |
418 m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
419 if(m_sVhdr2->bmiHeader.biCompression == 3) | |
420 m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; | |
421 else | |
422 m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); | |
423 | |
424 return 1; | |
425 } | |
426 | |
427 m_decoder = m_obh; | |
428 | |
429 // m_obh=temp; | |
430 // if(csp) | |
431 // m_obh.biBitCount=BitmapInfo::BitCount(csp); | |
432 m_bh->biBitCount = bits; | |
433 | |
434 //Restart(); | |
435 bool stoped = false; | |
436 if (m_State == START) | |
437 { | |
438 Stop(); | |
439 stoped = true; | |
440 } | |
441 | |
442 m_pDS_Filter->m_pInputPin->vt->Disconnect(m_pDS_Filter->m_pInputPin); | |
443 m_pDS_Filter->m_pOutputPin->vt->Disconnect(m_pDS_Filter->m_pOutputPin); | |
444 m_pDS_Filter->m_pOurOutput->SetNewFormat(m_sDestType); | |
445 result = m_pDS_Filter->m_pInputPin->vt->ReceiveConnection(m_pDS_Filter->m_pInputPin, | |
446 m_pDS_Filter->m_pOurInput, | |
447 &m_sOurType); | |
448 if (result) | |
449 { | |
450 cerr<<"Error reconnecting input pin "<<hex<<result<<dec<<endl; | |
451 return -1; | |
452 } | |
453 result = m_pDS_Filter->m_pOutputPin->vt->ReceiveConnection(m_pDS_Filter->m_pOutputPin, | |
454 m_pDS_Filter->m_pOurOutput, | |
455 &m_sDestType); | |
456 if (result) | |
457 { | |
458 cerr<<"Error reconnecting output pin "<<hex<<result<<dec<<endl; | |
459 return -1; | |
460 } | |
461 | |
462 if (stoped) | |
463 Start(); | |
464 | |
465 return 0; | |
466 } | |
467 | |
468 HRESULT DS_VideoDecoder::GetValue(const char* name, int& value) | |
469 { | |
470 if (m_bIsDivX) | |
471 { | |
472 if (m_State != START) | |
473 return VFW_E_NOT_RUNNING; | |
474 // brightness 87 | |
475 // contrast 74 | |
476 // hue 23 | |
477 // saturation 20 | |
478 // post process mode 0 | |
479 // get1 0x01 | |
480 // get2 10 | |
481 // get3=set2 86 | |
482 // get4=set3 73 | |
483 // get5=set4 19 | |
484 // get6=set5 23 | |
485 IHidden* hidden=(IHidden*)((int)m_pDS_Filter->m_pFilter+0xb8); | |
486 if (strcmp(name, "Brightness") == 0) | |
487 return hidden->vt->GetSmth3(hidden, &value); | |
488 if (strcmp(name, "Contrast") == 0) | |
489 return hidden->vt->GetSmth4(hidden, &value); | |
490 if (strcmp(name, "Hue") == 0) | |
491 return hidden->vt->GetSmth6(hidden, &value); | |
492 if (strcmp(name, "Saturation") == 0) | |
493 return hidden->vt->GetSmth5(hidden, &value); | |
494 if (strcmp(name, "Quality") == 0) | |
495 { | |
496 #warning NOT SURE | |
497 int r = hidden->vt->GetSmth2(hidden, &value); | |
498 if (value >= 10) | |
499 value -= 10; | |
500 return 0; | |
501 } | |
502 } | |
503 else if (record.dll == string("ir50_32.dll")) | |
504 { | |
505 IHidden2* hidden = 0; | |
506 if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden)) | |
507 { | |
508 cerr << "No such interface" << endl; | |
509 return -1; | |
510 } | |
511 #warning FIXME | |
512 int recordpar[30]; | |
513 recordpar[0]=0x7c; | |
514 recordpar[1]=fccIV50; | |
515 recordpar[2]=0x10005; | |
516 recordpar[3]=2; | |
517 recordpar[4]=1; | |
518 recordpar[5]=0x80000000; | |
519 | |
520 if (strcmp(name, "Brightness") == 0) | |
521 recordpar[5]|=0x20; | |
522 else if (strcmp(name, "Saturation") == 0) | |
523 recordpar[5]|=0x40; | |
524 else if (strcmp(name, "Contrast") == 0) | |
525 recordpar[5]|=0x80; | |
526 if (!recordpar[5]) | |
527 { | |
528 hidden->vt->Release((IUnknown*)hidden); | |
529 return -1; | |
530 } | |
531 if (hidden->vt->DecodeSet(hidden, recordpar)) | |
532 return -1; | |
533 | |
534 if (strcmp(name, "Brightness") == 0) | |
535 value = recordpar[18]; | |
536 else if (strcmp(name, "Saturation") == 0) | |
537 value = recordpar[19]; | |
538 else if (strcmp(name, "Contrast") == 0) | |
539 value = recordpar[20]; | |
540 | |
541 hidden->vt->Release((IUnknown*)hidden); | |
542 } | |
543 | |
544 return 0; | |
545 } | |
546 | |
547 HRESULT DS_VideoDecoder::SetValue(const char* name, int value) | |
548 { | |
549 if (m_bIsDivX) | |
550 { | |
551 if (m_State != START) | |
552 return VFW_E_NOT_RUNNING; | |
553 | |
554 //cout << "set value " << name << " " << value << endl; | |
555 // brightness 87 | |
556 // contrast 74 | |
557 // hue 23 | |
558 // saturation 20 | |
559 // post process mode 0 | |
560 // get1 0x01 | |
561 // get2 10 | |
562 // get3=set2 86 | |
563 // get4=set3 73 | |
564 // get5=set4 19 | |
565 // get6=set5 23 | |
566 IHidden* hidden = (IHidden*)((int)m_pDS_Filter->m_pFilter + 0xb8); | |
567 if (strcmp(name, "Quality") == 0) | |
568 { | |
569 m_iLastQuality = value; | |
570 return hidden->vt->SetSmth(hidden, value, 0); | |
571 } | |
572 if (strcmp(name, "Brightness") == 0) | |
573 return hidden->vt->SetSmth2(hidden, value, 0); | |
574 if (strcmp(name, "Contrast") == 0) | |
575 return hidden->vt->SetSmth3(hidden, value, 0); | |
576 if (strcmp(name, "Saturation") == 0) | |
577 return hidden->vt->SetSmth4(hidden, value, 0); | |
578 if (strcmp(name, "Hue") == 0) | |
579 return hidden->vt->SetSmth5(hidden, value, 0); | |
580 } | |
581 else if (record.dll == string("ir50_32.dll")) | |
582 { | |
583 IHidden2* hidden = 0; | |
584 if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden)) | |
585 { | |
586 Debug cerr << "No such interface" << endl; | |
587 return -1; | |
588 } | |
589 int recordpar[30]; | |
590 recordpar[0]=0x7c; | |
591 recordpar[1]=fccIV50; | |
592 recordpar[2]=0x10005; | |
593 recordpar[3]=2; | |
594 recordpar[4]=1; | |
595 recordpar[5]=0x80000000; | |
596 if (strcmp(name, "Brightness") == 0) | |
597 { | |
598 recordpar[5]|=0x20; | |
599 recordpar[18]=value; | |
600 } | |
601 else if (strcmp(name, "Saturation") == 0) | |
602 { | |
603 recordpar[5]|=0x40; | |
604 recordpar[19]=value; | |
605 } | |
606 else if (strcmp(name, "Contrast") == 0) | |
607 { | |
608 recordpar[5]|=0x80; | |
609 recordpar[20]=value; | |
610 } | |
611 if(!recordpar[5]) | |
612 { | |
613 hidden->vt->Release((IUnknown*)hidden); | |
614 return -1; | |
615 } | |
616 HRESULT result = hidden->vt->DecodeSet(hidden, recordpar); | |
617 hidden->vt->Release((IUnknown*)hidden); | |
618 | |
619 return result; | |
620 } | |
621 return 0; | |
622 } | |
623 /* | |
624 vim: tabstop=8 | |
625 */ |