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