1 /********************************************************
3 DirectShow Video decoder implementation
4 Copyright 2000 Eugene Kuznetsov (divx@euro.ru)
6 *********************************************************/
9 #include "interfaces.h"
10 #include "loader/registry.h"
12 #include "DS_Filter.h"
14 struct DS_VideoDecoder
18 DS_Filter
* m_pDS_Filter
;
19 AM_MEDIA_TYPE m_sOurType
, m_sDestType
;
20 VIDEOINFOHEADER
* m_sVhdr
;
21 VIDEOINFOHEADER
* m_sVhdr2
;
22 int m_Caps
;//CAPS m_Caps; // capabilities of DirectShow decoder
23 int m_iLastQuality
; // remember last quality as integer
26 int m_bIsDivX
; // for speed
27 int m_bIsDivX4
; // for speed
29 static SampleProcUserData sampleProcData
;
31 #include "DS_VideoDecoder.h"
33 #include "loader/wine/winerror.h"
35 #include "loader/ldt_keeper.h"
41 #include <sys/types.h>
42 #ifdef HAVE_SYS_MMAN_H
46 #include <stdlib.h> // labs
48 // strcmp((const char*)info.dll,...) is used instead of (... == ...)
49 // so Arpi could use char* pointer in his simplified DS_VideoDecoder class
54 int DS_VideoDecoder_GetCapabilities(DS_VideoDecoder
*this)
55 {return this->m_Caps
;}
67 {16, fccYUY2
, &MEDIASUBTYPE_YUY2
, CAP_YUY2
},
68 {12, fccIYUV
, &MEDIASUBTYPE_IYUV
, CAP_IYUV
},
69 {16, fccUYVY
, &MEDIASUBTYPE_UYVY
, CAP_UYVY
},
70 {12, fccYV12
, &MEDIASUBTYPE_YV12
, CAP_YV12
},
71 //{16, fccYV12, &MEDIASUBTYPE_YV12, CAP_YV12},
72 {16, fccYVYU
, &MEDIASUBTYPE_YVYU
, CAP_YVYU
},
73 {12, fccI420
, &MEDIASUBTYPE_I420
, CAP_I420
},
74 {9, fccYVU9
, &MEDIASUBTYPE_YVU9
, CAP_YVU9
},
79 DS_VideoDecoder
* DS_VideoDecoder_Open(char* dllname
, GUID
* guid
, BITMAPINFOHEADER
* format
, int flip
, int maxauto
)
81 DS_VideoDecoder
*this;
85 this = malloc(sizeof(DS_VideoDecoder
));
86 memset( this, 0, sizeof(DS_VideoDecoder
));
89 this->m_iLastQuality
= -1;
90 this->m_iMaxAuto
= maxauto
;
96 //memset(&m_obh, 0, sizeof(m_obh));
97 //m_obh.biSize = sizeof(m_obh);
102 bihs
= (format
->biSize
< (int) sizeof(BITMAPINFOHEADER
)) ?
103 sizeof(BITMAPINFOHEADER
) : format
->biSize
;
105 this->iv
.m_bh
= malloc(bihs
);
106 memcpy(this->iv
.m_bh
, format
, bihs
);
107 this->iv
.m_bh
->biSize
= bihs
;
109 this->iv
.m_State
= STOP
;
110 //this->iv.m_pFrame = 0;
111 this->iv
.m_Mode
= DIRECT
;
112 this->iv
.m_iDecpos
= 0;
113 this->iv
.m_iPlaypos
= -1;
114 this->iv
.m_fQuality
= 0.0f
;
115 this->iv
.m_bCapable16b
= true;
117 bihs
+= sizeof(VIDEOINFOHEADER
) - sizeof(BITMAPINFOHEADER
);
118 this->m_sVhdr
= malloc(bihs
);
119 memset(this->m_sVhdr
, 0, bihs
);
120 memcpy(&this->m_sVhdr
->bmiHeader
, this->iv
.m_bh
, this->iv
.m_bh
->biSize
);
121 this->m_sVhdr
->rcSource
.left
= this->m_sVhdr
->rcSource
.top
= 0;
122 this->m_sVhdr
->rcSource
.right
= this->m_sVhdr
->bmiHeader
.biWidth
;
123 this->m_sVhdr
->rcSource
.bottom
= this->m_sVhdr
->bmiHeader
.biHeight
;
124 //this->m_sVhdr->rcSource.right = 0;
125 //this->m_sVhdr->rcSource.bottom = 0;
126 this->m_sVhdr
->rcTarget
= this->m_sVhdr
->rcSource
;
128 this->m_sOurType
.majortype
= MEDIATYPE_Video
;
129 this->m_sOurType
.subtype
= MEDIATYPE_Video
;
130 this->m_sOurType
.subtype
.f1
= this->m_sVhdr
->bmiHeader
.biCompression
;
131 this->m_sOurType
.formattype
= FORMAT_VideoInfo
;
132 this->m_sOurType
.bFixedSizeSamples
= false;
133 this->m_sOurType
.bTemporalCompression
= true;
134 this->m_sOurType
.pUnk
= 0;
135 this->m_sOurType
.cbFormat
= bihs
;
136 this->m_sOurType
.pbFormat
= (char*)this->m_sVhdr
;
138 this->m_sVhdr2
= malloc(sizeof(VIDEOINFOHEADER
)+12);
139 memcpy(this->m_sVhdr2
, this->m_sVhdr
, sizeof(VIDEOINFOHEADER
));
140 memset((char*)this->m_sVhdr2
+ sizeof(VIDEOINFOHEADER
), 0, 12);
141 this->m_sVhdr2
->bmiHeader
.biCompression
= 0;
142 this->m_sVhdr2
->bmiHeader
.biBitCount
= 24;
144 memset(&this->m_sDestType
, 0, sizeof(this->m_sDestType
));
145 this->m_sDestType
.majortype
= MEDIATYPE_Video
;
146 this->m_sDestType
.subtype
= MEDIASUBTYPE_RGB24
;
147 this->m_sDestType
.formattype
= FORMAT_VideoInfo
;
148 this->m_sDestType
.bFixedSizeSamples
= true;
149 this->m_sDestType
.bTemporalCompression
= false;
150 this->m_sDestType
.lSampleSize
= labs(this->m_sVhdr2
->bmiHeader
.biWidth
*this->m_sVhdr2
->bmiHeader
.biHeight
151 * ((this->m_sVhdr2
->bmiHeader
.biBitCount
+ 7) / 8));
152 this->m_sVhdr2
->bmiHeader
.biSizeImage
= this->m_sDestType
.lSampleSize
;
153 this->m_sDestType
.pUnk
= 0;
154 this->m_sDestType
.cbFormat
= sizeof(VIDEOINFOHEADER
);
155 this->m_sDestType
.pbFormat
= (char*)this->m_sVhdr2
;
157 memset(&this->iv
.m_obh
, 0, sizeof(this->iv
.m_obh
));
158 memcpy(&this->iv
.m_obh
, this->iv
.m_bh
, sizeof(this->iv
.m_obh
) < (unsigned) this->iv
.m_bh
->biSize
159 ? sizeof(this->iv
.m_obh
) : (unsigned) this->iv
.m_bh
->biSize
);
160 this->iv
.m_obh
.biBitCount
=24;
161 this->iv
.m_obh
.biSize
= sizeof(BITMAPINFOHEADER
);
162 this->iv
.m_obh
.biCompression
= 0; //BI_RGB
163 //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight);
164 this->iv
.m_obh
.biSizeImage
= labs(this->iv
.m_obh
.biWidth
* this->iv
.m_obh
.biHeight
)
165 * ((this->iv
.m_obh
.biBitCount
+ 7) / 8);
168 this->m_pDS_Filter
= DS_FilterCreate(dllname
, guid
, &this->m_sOurType
, &this->m_sDestType
,&sampleProcData
);
170 if (!this->m_pDS_Filter
)
172 printf("Failed to create DirectShow filter\n");
178 this->iv
.m_obh
.biHeight
*= -1;
179 this->m_sVhdr2
->bmiHeader
.biHeight
= this->iv
.m_obh
.biHeight
;
180 result
= this->m_pDS_Filter
->m_pOutputPin
->vt
->QueryAccept(this->m_pDS_Filter
->m_pOutputPin
, &this->m_sDestType
);
183 printf("Decoder does not support upside-down RGB frames\n");
184 this->iv
.m_obh
.biHeight
*= -1;
185 this->m_sVhdr2
->bmiHeader
.biHeight
= this->iv
.m_obh
.biHeight
;
189 memcpy( &this->iv
.m_decoder
, &this->iv
.m_obh
, sizeof(this->iv
.m_obh
) );
191 switch (this->iv
.m_bh
->biCompression
)
200 //YV12 seems to be broken for DivX :-) codec
202 //produces incorrect picture
203 //m_Caps = (CAPS) (m_Caps & ~CAP_YV12);
204 //m_Caps = CAP_UYVY;//CAP_YUY2; // | CAP_I420;
206 this->m_Caps
= (CAP_YUY2
| CAP_UYVY
);
211 this->m_Caps
= CAP_NONE
;
213 printf("Decoder supports the following YUV formats: ");
214 for (c
= check
; c
->bits
; c
++)
216 this->m_sVhdr2
->bmiHeader
.biBitCount
= c
->bits
;
217 this->m_sVhdr2
->bmiHeader
.biCompression
= c
->fcc
;
218 this->m_sDestType
.subtype
= *c
->subtype
;
219 result
= this->m_pDS_Filter
->m_pOutputPin
->vt
->QueryAccept(this->m_pDS_Filter
->m_pOutputPin
, &this->m_sDestType
);
222 this->m_Caps
= (this->m_Caps
| c
->cap
);
223 printf("%.4s ", (char *)&c
->fcc
);
229 if (this->m_Caps
!= CAP_NONE
)
230 printf("Decoder is capable of YUV output (flags 0x%x)\n", (int)this->m_Caps
);
232 this->m_sVhdr2
->bmiHeader
.biBitCount
= 24;
233 this->m_sVhdr2
->bmiHeader
.biCompression
= 0;
234 this->m_sDestType
.subtype
= MEDIASUBTYPE_RGB24
;
236 this->m_iMinBuffers
= this->iv
.VBUFSIZE
;
237 this->m_bIsDivX
= (strcmp(dllname
, "divxcvki.ax") == 0
238 || strcmp(dllname
, "divx_c32.ax") == 0
239 || strcmp(dllname
, "wmvds32.ax") == 0
240 || strcmp(dllname
, "wmv8ds32.ax") == 0);
241 this->m_bIsDivX4
= (strcmp(dllname
, "divxdec.ax") == 0);
243 this->iv
.VBUFSIZE
+= 7;
244 else if (this->m_bIsDivX4
)
245 this->iv
.VBUFSIZE
+= 9;
247 /*catch (FatalError& error)
257 void DS_VideoDecoder_Destroy(DS_VideoDecoder
*this)
259 DS_VideoDecoder_StopInternal(this);
260 this->iv
.m_State
= STOP
;
262 free(this->m_sVhdr2
);
263 DS_Filter_Destroy(this->m_pDS_Filter
);
266 void DS_VideoDecoder_StartInternal(DS_VideoDecoder
*this)
268 Debug
printf("DS_VideoDecoder_StartInternal\n");
269 //cout << "DSSTART" << endl;
270 this->m_pDS_Filter
->m_pAll
->vt
->Commit(this->m_pDS_Filter
->m_pAll
);
271 this->m_pDS_Filter
->Start(this->m_pDS_Filter
);
273 this->iv
.m_State
= START
;
276 void DS_VideoDecoder_StopInternal(DS_VideoDecoder
*this)
278 this->m_pDS_Filter
->Stop(this->m_pDS_Filter
);
279 //??? why was this here ??? m_pOurOutput->SetFramePointer(0);
282 int DS_VideoDecoder_DecodeInternal(DS_VideoDecoder
*this, const void* src
, int size
, int is_keyframe
, char* pImage
)
284 IMediaSample
* sample
= 0;
288 Debug
printf("DS_VideoDecoder_DecodeInternal(%p,%p,%d,%d,%p)\n",this,src
,size
,is_keyframe
,pImage
);
290 this->m_pDS_Filter
->m_pAll
->vt
->GetBuffer(this->m_pDS_Filter
->m_pAll
, &sample
, 0, 0, 0);
294 Debug
printf("ERROR: null sample\n");
298 //cout << "DECODE " << (void*) pImage << " d: " << (void*) pImage->Data() << endl;
301 sample
->vt
->SetActualDataLength(sample
, size
);
302 sample
->vt
->GetPointer(sample
, (BYTE
**)&ptr
);
303 memcpy(ptr
, src
, size
);
304 sample
->vt
->SetSyncPoint(sample
, is_keyframe
);
305 sample
->vt
->SetPreroll(sample
, pImage
? 0 : 1);
306 // sample->vt->SetMediaType(sample, &m_sOurType);
308 // FIXME: - crashing with YV12 at this place decoder will crash
309 // while doing this call
310 // %FS register was not setup for calling into win32 dll. Are all
311 // crashes inside ...->Receive() fixed now?
313 // nope - but this is surely helpfull - I'll try some more experiments
318 if (!this->m_pDS_Filter
|| !this->m_pDS_Filter
->m_pImp
319 || !this->m_pDS_Filter
->m_pImp
->vt
320 || !this->m_pDS_Filter
->m_pImp
->vt
->Receive
)
321 printf("DecodeInternal ERROR???\n");
323 result
= this->m_pDS_Filter
->m_pImp
->vt
->Receive(this->m_pDS_Filter
->m_pImp
, sample
);
326 Debug
printf("DS_VideoDecoder::DecodeInternal() error putting data into input pin %x\n", result
);
330 memcpy(pImage
, sampleProcData
.frame_pointer
, sampleProcData
.frame_size
);
332 sample
->vt
->Release((IUnknown
*)sample
);
338 IHidden
* hidden
=(IHidden
*)((int)this->m_pDS_Filter
->m_pFilter
+ 0xb8);
339 // always check for actual value
340 // this seems to be the only way to know the actual value
341 hidden
->vt
->GetSmth2(hidden
, &this->m_iLastQuality
);
342 if (this->m_iLastQuality
> 9)
343 this->m_iLastQuality
-= 10;
345 if (this->m_iLastQuality
< 0)
346 this->m_iLastQuality
= 0;
347 else if (this->m_iLastQuality
> this->m_iMaxAuto
)
348 this->m_iLastQuality
= this->m_iMaxAuto
;
350 //cout << " Qual: " << this->m_iLastQuality << endl;
351 this->iv
.m_fQuality
= this->m_iLastQuality
/ 4.0;
353 else if (this->m_bIsDivX4
)
356 // maybe access methods directly to safe some cpu cycles...
357 DS_VideoDecoder_GetValue(this, "Postprocessing", this->m_iLastQuality
);
358 if (this->m_iLastQuality
< 0)
359 this->m_iLastQuality
= 0;
360 else if (this->m_iLastQuality
> this->m_iMaxAuto
)
361 this->m_iLastQuality
= this->m_iMaxAuto
;
363 //cout << " Qual: " << m_iLastQuality << endl;
364 this->iv
.m_fQuality
= this->m_iLastQuality
/ 6.0;
367 if (this->iv
.m_Mode
== -1 ) // ???BUFFERED_QUALITY_AUTO)
369 // adjust Quality - depends on how many cached frames we have
370 int buffered
= this->iv
.m_iDecpos
- this->iv
.m_iPlaypos
;
372 if (this->m_bIsDivX
|| this->m_bIsDivX4
)
374 int to
= buffered
- this->m_iMinBuffers
;
377 if (to
!= this->m_iLastQuality
)
379 if (to
> this->m_iMaxAuto
)
380 to
= this->m_iMaxAuto
;
381 if (this->m_iLastQuality
!= to
)
385 IHidden
* hidden
=(IHidden
*)((int)this->m_pDS_Filter
->m_pFilter
+ 0xb8);
386 hidden
->vt
->SetSmth(hidden
, to
, 0);
389 DS_VideoDecoder_SetValue(this, "Postprocessing", to
);
391 //printf("Switching quality %d -> %d b:%d\n",m_iLastQuality, to, buffered);
403 * bits == 0 - leave unchanged
405 //int SetDestFmt(DS_VideoDecoder * this, int bits = 24, fourcc_t csp = 0);
406 int DS_VideoDecoder_SetDestFmt(DS_VideoDecoder
*this, int bits
, unsigned int csp
)
409 ALLOCATOR_PROPERTIES props
,props1
;
413 Debug
printf("DS_VideoDecoder_SetDestFmt (%p, %d, %d)\n",this,bits
,(int)csp
);
415 /* if (!CImage::Supported(csp, bits))
418 // BitmapInfo temp = m_obh;
427 this->m_sDestType
.subtype
= MEDIASUBTYPE_RGB555
;
430 this->m_sDestType
.subtype
= MEDIASUBTYPE_RGB565
;
433 this->m_sDestType
.subtype
= MEDIASUBTYPE_RGB24
;
436 this->m_sDestType
.subtype
= MEDIASUBTYPE_RGB32
;
445 this->iv
.m_obh
.biBitCount
=16;
447 this->iv
.m_obh
.biBitCount
=bits
;
448 if( bits
== 15 || bits
== 16 ) {
449 this->iv
.m_obh
.biSize
=sizeof(BITMAPINFOHEADER
)+12;
450 this->iv
.m_obh
.biCompression
=3;//BI_BITFIELDS
451 this->iv
.m_obh
.biSizeImage
=abs((int)(2*this->iv
.m_obh
.biWidth
*this->iv
.m_obh
.biHeight
));
455 this->iv
.m_obh
.colors
[0]=0xF800;
456 this->iv
.m_obh
.colors
[1]=0x07E0;
457 this->iv
.m_obh
.colors
[2]=0x001F;
458 } else if ( bits
== 15 ) {
459 this->iv
.m_obh
.colors
[0]=0x7C00;
460 this->iv
.m_obh
.colors
[1]=0x03E0;
461 this->iv
.m_obh
.colors
[2]=0x001F;
463 this->iv
.m_obh
.biSize
= sizeof(BITMAPINFOHEADER
);
464 this->iv
.m_obh
.biCompression
= 0; //BI_RGB
465 //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight);
466 this->iv
.m_obh
.biSizeImage
= labs(this->iv
.m_obh
.biWidth
* this->iv
.m_obh
.biHeight
)
467 * ((this->iv
.m_obh
.biBitCount
+ 7) / 8);
470 //.biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8));
477 this->m_sDestType
.subtype
= MEDIASUBTYPE_YUY2
;
480 this->m_sDestType
.subtype
= MEDIASUBTYPE_YV12
;
483 this->m_sDestType
.subtype
= MEDIASUBTYPE_IYUV
;
486 this->m_sDestType
.subtype
= MEDIASUBTYPE_I420
;
489 this->m_sDestType
.subtype
= MEDIASUBTYPE_UYVY
;
492 this->m_sDestType
.subtype
= MEDIASUBTYPE_YVYU
;
495 this->m_sDestType
.subtype
= MEDIASUBTYPE_YVU9
;
502 if (csp
!= 0 && csp
!= 3 && this->iv
.m_obh
.biHeight
> 0)
503 this->iv
.m_obh
.biHeight
*= -1; // YUV formats uses should have height < 0
504 this->iv
.m_obh
.biSize
= sizeof(BITMAPINFOHEADER
);
505 this->iv
.m_obh
.biCompression
=csp
;
506 this->iv
.m_obh
.biBitCount
=bits
;
507 this->iv
.m_obh
.biSizeImage
=labs(this->iv
.m_obh
.biBitCount
*
508 this->iv
.m_obh
.biWidth
*this->iv
.m_obh
.biHeight
)>>3;
511 this->m_sDestType
.lSampleSize
= this->iv
.m_obh
.biSizeImage
;
512 memcpy(&(this->m_sVhdr2
->bmiHeader
), &this->iv
.m_obh
, sizeof(this->iv
.m_obh
));
513 this->m_sVhdr2
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
514 if (this->m_sVhdr2
->bmiHeader
.biCompression
== 3)
515 this->m_sDestType
.cbFormat
= sizeof(VIDEOINFOHEADER
) + 12;
517 this->m_sDestType
.cbFormat
= sizeof(VIDEOINFOHEADER
);
523 if(!(this->m_Caps
& CAP_YUY2
))
527 if(!(this->m_Caps
& CAP_YV12
))
531 if(!(this->m_Caps
& CAP_IYUV
))
535 if(!(this->m_Caps
& CAP_I420
))
539 if(!(this->m_Caps
& CAP_UYVY
))
543 if(!(this->m_Caps
& CAP_YVYU
))
547 if(!(this->m_Caps
& CAP_YVU9
))
552 result
= this->m_pDS_Filter
->m_pOutputPin
->vt
->QueryAccept(this->m_pDS_Filter
->m_pOutputPin
, &this->m_sDestType
);
559 printf("Warning: unsupported color space\n");
561 printf("Warning: unsupported bit depth\n");
563 this->m_sDestType
.lSampleSize
= this->iv
.m_decoder
.biSizeImage
;
564 memcpy(&(this->m_sVhdr2
->bmiHeader
), &this->iv
.m_decoder
, sizeof(this->iv
.m_decoder
));
565 this->m_sVhdr2
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
566 if (this->m_sVhdr2
->bmiHeader
.biCompression
== 3)
567 this->m_sDestType
.cbFormat
= sizeof(VIDEOINFOHEADER
) + 12;
569 this->m_sDestType
.cbFormat
= sizeof(VIDEOINFOHEADER
);
574 memcpy( &this->iv
.m_decoder
, &this->iv
.m_obh
, sizeof(this->iv
.m_obh
));
578 // m_obh.biBitCount=BitmapInfo::BitCount(csp);
579 this->iv
.m_bh
->biBitCount
= bits
;
581 //DS_VideoDecoder_Restart(this);
583 if (this->iv
.m_State
== START
)
585 DS_VideoDecoder_StopInternal(this);
586 this->iv
.m_State
= STOP
;
590 this->m_pDS_Filter
->m_pInputPin
->vt
->Disconnect(this->m_pDS_Filter
->m_pInputPin
);
591 this->m_pDS_Filter
->m_pOutputPin
->vt
->Disconnect(this->m_pDS_Filter
->m_pOutputPin
);
592 this->m_pDS_Filter
->m_pOurOutput
->SetNewFormat(this->m_pDS_Filter
->m_pOurOutput
,&this->m_sDestType
);
593 result
= this->m_pDS_Filter
->m_pInputPin
->vt
->ReceiveConnection(this->m_pDS_Filter
->m_pInputPin
,
594 this->m_pDS_Filter
->m_pOurInput
,
598 printf("Error reconnecting input pin 0x%x\n", (int)result
);
602 if(this->m_pDS_Filter
->m_pAll
)
603 this->m_pDS_Filter
->m_pAll
->vt
->Release(this->m_pDS_Filter
->m_pAll
);
604 this->m_pDS_Filter
->m_pAll
=MemAllocatorCreate();
605 if (!this->m_pDS_Filter
->m_pAll
)
607 printf("Call to MemAllocatorCreate failed\n");
610 //Seting allocator property according to our media type
612 props
.cbBuffer
=this->m_sDestType
.lSampleSize
;
615 this->m_pDS_Filter
->m_pAll
->vt
->SetProperties(this->m_pDS_Filter
->m_pAll
, &props
, &props1
);
616 //Notify remote pin about choosed allocator
617 this->m_pDS_Filter
->m_pImp
->vt
->NotifyAllocator(this->m_pDS_Filter
->m_pImp
, this->m_pDS_Filter
->m_pAll
, 0);
619 result
= this->m_pDS_Filter
->m_pOutputPin
->vt
->ReceiveConnection(this->m_pDS_Filter
->m_pOutputPin
,
620 (IPin
*)this->m_pDS_Filter
->m_pOurOutput
,
624 printf("Error reconnecting output pin 0x%x\n", (int)result
);
630 DS_VideoDecoder_StartInternal(this);
631 this->iv
.m_State
= START
;
638 int DS_VideoDecoder_SetDirection(DS_VideoDecoder
*this, int d
)
640 this->iv
.m_obh
.biHeight
= (d
) ? this->iv
.m_bh
->biHeight
: -this->iv
.m_bh
->biHeight
;
641 this->m_sVhdr2
->bmiHeader
.biHeight
= this->iv
.m_obh
.biHeight
;
645 int DS_VideoDecoder_GetValue(DS_VideoDecoder
*this, const char* name
, int* value
)
650 IDivxFilterInterface* pIDivx;
651 if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_IDivxFilterInterface, (void**)&pIDivx))
653 Debug printf("No such interface\n");
656 if (strcmp(name, "Postprocessing") == 0)
658 pIDivx->vt->get_PPLevel(pIDivx, &value);
661 else if (strcmp(name, "Brightness") == 0)
662 pIDivx->vt->get_Brightness(pIDivx, &value);
663 else if (strcmp(name, "Contrast") == 0)
664 pIDivx->vt->get_Contrast(pIDivx, &value);
665 else if (strcmp(name, "Saturation") == 0)
666 pIDivx->vt->get_Saturation(pIDivx, &value);
667 else if (strcmp(name, "MaxAuto") == 0)
669 pIDivx->vt->Release((IUnknown*)pIDivx);
674 if (m_State != START)
675 return VFW_E_NOT_RUNNING;
680 // post process mode 0
687 IHidden* hidden=(IHidden*)((int)m_pDS_Filter->m_pFilter+0xb8);
688 if (strcmp(name, "Quality") == 0)
691 int r = hidden->vt->GetSmth2(hidden, &value);
696 if (strcmp(name, "Brightness") == 0)
697 return hidden->vt->GetSmth3(hidden, &value);
698 if (strcmp(name, "Contrast") == 0)
699 return hidden->vt->GetSmth4(hidden, &value);
700 if (strcmp(name, "Hue") == 0)
701 return hidden->vt->GetSmth6(hidden, &value);
702 if (strcmp(name, "Saturation") == 0)
703 return hidden->vt->GetSmth5(hidden, &value);
704 if (strcmp(name, "MaxAuto") == 0)
710 else if (strcmp((const char*)record.dll, "ir50_32.dll") == 0)
712 IHidden2* hidden = 0;
713 if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden))
715 Debug printf("No such interface\n");
721 recordpar[1]=fccIV50;
722 recordpar[2]=0x10005;
725 recordpar[5]=0x80000000;
727 if (strcmp(name, "Brightness") == 0)
729 else if (strcmp(name, "Saturation") == 0)
731 else if (strcmp(name, "Contrast") == 0)
735 hidden->vt->Release((IUnknown*)hidden);
738 if (hidden->vt->DecodeSet(hidden, recordpar))
741 if (strcmp(name, "Brightness") == 0)
742 value = recordpar[18];
743 else if (strcmp(name, "Saturation") == 0)
744 value = recordpar[19];
745 else if (strcmp(name, "Contrast") == 0)
746 value = recordpar[20];
748 hidden->vt->Release((IUnknown*)hidden);
754 int DS_VideoDecoder_SetValue(DS_VideoDecoder
*this, const char* name
, int value
)
756 if (this->m_bIsDivX4
) {
757 IDivxFilterInterface
* pIDivx
=NULL
;
758 // printf("DS_SetValue for DIVX4, name=%s value=%d\n",name,value);
759 if (this->m_pDS_Filter
->m_pFilter
->vt
->QueryInterface((IUnknown
*)this->m_pDS_Filter
->m_pFilter
, &IID_IDivxFilterInterface
, (void**)&pIDivx
))
761 printf("No such interface\n");
764 if (strcasecmp(name
, "Postprocessing") == 0)
765 pIDivx
->vt
->put_PPLevel(pIDivx
, value
* 10);
766 else if (strcasecmp(name
, "Brightness") == 0)
767 pIDivx
->vt
->put_Brightness(pIDivx
, value
);
768 else if (strcasecmp(name
, "Contrast") == 0)
769 pIDivx
->vt
->put_Contrast(pIDivx
, value
);
770 else if (strcasecmp(name
, "Saturation") == 0)
771 pIDivx
->vt
->put_Saturation(pIDivx
, value
);
772 else if (strcasecmp(name
, "MaxAuto") == 0)
773 this->m_iMaxAuto
= value
;
774 pIDivx
->vt
->Release((IUnknown
*)pIDivx
);
775 //printf("Set %s %d\n", name, value);
779 if (this->m_bIsDivX
) {
781 if (this->iv
.m_State
!= START
)
782 return VFW_E_NOT_RUNNING
;
784 //cout << "set value " << name << " " << value << endl;
789 // post process mode 0
796 hidden
= (IHidden
*)((int)this->m_pDS_Filter
->m_pFilter
+ 0xb8);
797 //printf("DS_SetValue for DIVX, name=%s value=%d\n",name,value);
798 if (strcasecmp(name
, "Quality") == 0)
800 this->m_iLastQuality
= value
;
801 return hidden
->vt
->SetSmth(hidden
, value
, 0);
803 if (strcasecmp(name
, "Brightness") == 0)
804 return hidden
->vt
->SetSmth2(hidden
, value
, 0);
805 if (strcasecmp(name
, "Contrast") == 0)
806 return hidden
->vt
->SetSmth3(hidden
, value
, 0);
807 if (strcasecmp(name
, "Saturation") == 0)
808 return hidden
->vt
->SetSmth4(hidden
, value
, 0);
809 if (strcasecmp(name
, "Hue") == 0)
810 return hidden
->vt
->SetSmth5(hidden
, value
, 0);
811 if (strcasecmp(name
, "MaxAuto") == 0)
813 this->m_iMaxAuto
= value
;
818 if (strcmp((const char*)record
.dll
, "ir50_32.dll") == 0)
820 IHidden2
* hidden
= 0;
821 if (m_pDS_Filter
->m_pFilter
->vt
->QueryInterface((IUnknown
*)m_pDS_Filter
->m_pFilter
, &IID_Iv50Hidden
, (void**)&hidden
))
823 Debug
printf("No such interface\n");
828 recordpar
[1]=fccIV50
;
829 recordpar
[2]=0x10005;
832 recordpar
[5]=0x80000000;
833 if (strcmp(name
, "Brightness") == 0)
838 else if (strcmp(name
, "Saturation") == 0)
843 else if (strcmp(name
, "Contrast") == 0)
850 hidden
->vt
->Release((IUnknown
*)hidden
);
853 HRESULT result
= hidden
->vt
->DecodeSet(hidden
, recordpar
);
854 hidden
->vt
->Release((IUnknown
*)hidden
);
859 // printf("DS_SetValue for ????, name=%s value=%d\n",name,value);
863 int DS_SetAttr_DivX(char* attribute
, int value
){
864 int result
, status
, newkey
;
865 if(strcasecmp(attribute
, "Quality")==0){
866 char* keyname
="SOFTWARE\\Microsoft\\Scrunch";
867 result
=RegCreateKeyExA(HKEY_CURRENT_USER
, keyname
, 0, 0, 0, 0, 0, &newkey
, &status
);
870 printf("VideoDecoder::SetExtAttr: registry failure\n");
873 result
=RegSetValueExA(newkey
, "Current Post Process Mode", 0, REG_DWORD
, &value
, 4);
876 printf("VideoDecoder::SetExtAttr: error writing value\n");
880 result
=RegSetValueExA(newkey
, "Force Post Process Mode", 0, REG_DWORD
, &value
, 4);
883 printf("VideoDecoder::SetExtAttr: error writing value\n");
891 (strcasecmp(attribute
, "Saturation")==0) ||
892 (strcasecmp(attribute
, "Hue")==0) ||
893 (strcasecmp(attribute
, "Contrast")==0) ||
894 (strcasecmp(attribute
, "Brightness")==0)
897 char* keyname
="SOFTWARE\\Microsoft\\Scrunch\\Video";
898 result
=RegCreateKeyExA(HKEY_CURRENT_USER
, keyname
, 0, 0, 0, 0, 0, &newkey
, &status
);
901 printf("VideoDecoder::SetExtAttr: registry failure\n");
904 result
=RegSetValueExA(newkey
, attribute
, 0, REG_DWORD
, &value
, 4);
907 printf("VideoDecoder::SetExtAttr: error writing value\n");
914 printf("Unknown attribute!\n");