Mercurial > mplayer.hg
annotate loader/dshow/DS_VideoDecoder.c @ 22233:5bf6c178f09a
Move some subtitle handling from mplayer.c to mpcommon.c and share it with mencoder.c
author | reimar |
---|---|
date | Sat, 17 Feb 2007 21:04:46 +0000 |
parents | 88b36fd17976 |
children | 254733f57707 |
rev | line source |
---|---|
1545 | 1 /******************************************************** |
2 | |
3 DirectShow Video decoder implementation | |
4 Copyright 2000 Eugene Kuznetsov (divx@euro.ru) | |
5 | |
6 *********************************************************/ | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9581
diff
changeset
|
7 #include "config.h" |
1545 | 8 #include "guids.h" |
9 #include "interfaces.h" | |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
7316
diff
changeset
|
10 #include "registry.h" |
1545 | 11 |
3946 | 12 #ifndef NOAVIFILE_HEADERS |
13 #include "videodecoder.h" | |
14 #else | |
15 #include "libwin32.h" | |
16 #endif | |
17 #include "DS_Filter.h" | |
18 | |
19 struct _DS_VideoDecoder | |
20 { | |
21 IVideoDecoder iv; | |
22 | |
23 DS_Filter* m_pDS_Filter; | |
24 AM_MEDIA_TYPE m_sOurType, m_sDestType; | |
25 VIDEOINFOHEADER* m_sVhdr; | |
26 VIDEOINFOHEADER* m_sVhdr2; | |
27 int m_Caps;//CAPS m_Caps; // capabilities of DirectShow decoder | |
28 int m_iLastQuality; // remember last quality as integer | |
29 int m_iMinBuffers; | |
30 int m_iMaxAuto; | |
31 int m_bIsDivX; // for speed | |
32 int m_bIsDivX4; // for speed | |
33 }; | |
34 | |
1545 | 35 #include "DS_VideoDecoder.h" |
3946 | 36 |
3059 | 37 #include "../wine/winerror.h" |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9581
diff
changeset
|
38 #ifdef WIN32_LOADER |
8451 | 39 #include "../ldt_keeper.h" |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9581
diff
changeset
|
40 #endif |
3059 | 41 |
42 #ifndef NOAVIFILE_HEADERS | |
43 #define VFW_E_NOT_RUNNING 0x80040226 | |
44 #include "fourcc.h" | |
45 #include "except.h" | |
46 #endif | |
1545 | 47 |
48 #include <unistd.h> | |
49 #include <fcntl.h> | |
50 #include <errno.h> | |
51 #include <sys/types.h> | |
9978 | 52 #ifndef __MINGW32__ |
1545 | 53 #include <sys/mman.h> |
9978 | 54 #endif |
3059 | 55 #include <stdio.h> |
56 #include <stdlib.h> // labs | |
2072 | 57 |
3059 | 58 // strcmp((const char*)info.dll,...) is used instead of (... == ...) |
59 // so Arpi could use char* pointer in his simplified DS_VideoDecoder class | |
1545 | 60 |
3059 | 61 #define false 0 |
62 #define true 1 | |
63 | |
64 int DS_VideoDecoder_GetCapabilities(DS_VideoDecoder *this) | |
65 {return this->m_Caps;} | |
66 | |
67 typedef struct _ct ct; | |
1545 | 68 |
3059 | 69 struct _ct { |
70 unsigned int bits; | |
71 fourcc_t fcc; | |
8451 | 72 const GUID *subtype; |
3059 | 73 int cap; |
74 }; | |
75 | |
76 static ct check[] = { | |
77 {16, fccYUY2, &MEDIASUBTYPE_YUY2, CAP_YUY2}, | |
78 {12, fccIYUV, &MEDIASUBTYPE_IYUV, CAP_IYUV}, | |
79 {16, fccUYVY, &MEDIASUBTYPE_UYVY, CAP_UYVY}, | |
80 {12, fccYV12, &MEDIASUBTYPE_YV12, CAP_YV12}, | |
6527 | 81 //{16, fccYV12, &MEDIASUBTYPE_YV12, CAP_YV12}, |
3059 | 82 {16, fccYVYU, &MEDIASUBTYPE_YVYU, CAP_YVYU}, |
6527 | 83 {12, fccI420, &MEDIASUBTYPE_I420, CAP_I420}, |
84 {9, fccYVU9, &MEDIASUBTYPE_YVU9, CAP_YVU9}, | |
9581 | 85 {0, 0, 0, 0}, |
3059 | 86 }; |
87 | |
88 | |
3444 | 89 DS_VideoDecoder * DS_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto) |
1545 | 90 { |
3059 | 91 DS_VideoDecoder *this; |
92 HRESULT result; | |
93 ct* c; | |
94 | |
95 this = malloc(sizeof(DS_VideoDecoder)); | |
96 memset( this, 0, sizeof(DS_VideoDecoder)); | |
97 | |
98 this->m_sVhdr2 = 0; | |
99 this->m_iLastQuality = -1; | |
100 this->m_iMaxAuto = maxauto; | |
101 | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9581
diff
changeset
|
102 #ifdef WIN32_LOADER |
3063 | 103 Setup_LDT_Keeper(); |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9581
diff
changeset
|
104 #endif |
3063 | 105 |
1545 | 106 //memset(&m_obh, 0, sizeof(m_obh)); |
107 //m_obh.biSize = sizeof(m_obh); | |
3059 | 108 /*try*/ |
1545 | 109 { |
3059 | 110 unsigned int bihs; |
111 | |
112 bihs = (format->biSize < (int) sizeof(BITMAPINFOHEADER)) ? | |
113 sizeof(BITMAPINFOHEADER) : format->biSize; | |
114 | |
18878 | 115 this->iv.m_bh = malloc(bihs); |
3059 | 116 memcpy(this->iv.m_bh, format, bihs); |
22187
88b36fd17976
Precent overflow of this->m_sVhdr->bmiHeader buffer, may have been
rtogni
parents:
22001
diff
changeset
|
117 this->iv.m_bh->biSize = bihs; |
4205
c42ab0e5bbbc
possible sig11 fixed - noticed by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
3978
diff
changeset
|
118 |
3059 | 119 this->iv.m_State = STOP; |
120 //this->iv.m_pFrame = 0; | |
121 this->iv.m_Mode = DIRECT; | |
122 this->iv.m_iDecpos = 0; | |
123 this->iv.m_iPlaypos = -1; | |
124 this->iv.m_fQuality = 0.0f; | |
125 this->iv.m_bCapable16b = true; | |
126 | |
4205
c42ab0e5bbbc
possible sig11 fixed - noticed by Fredrik Kuivinen <freku045@student.liu.se>
arpi
parents:
3978
diff
changeset
|
127 bihs += sizeof(VIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER); |
18878 | 128 this->m_sVhdr = malloc(bihs); |
3059 | 129 memset(this->m_sVhdr, 0, bihs); |
130 memcpy(&this->m_sVhdr->bmiHeader, this->iv.m_bh, this->iv.m_bh->biSize); | |
131 this->m_sVhdr->rcSource.left = this->m_sVhdr->rcSource.top = 0; | |
132 this->m_sVhdr->rcSource.right = this->m_sVhdr->bmiHeader.biWidth; | |
133 this->m_sVhdr->rcSource.bottom = this->m_sVhdr->bmiHeader.biHeight; | |
134 //this->m_sVhdr->rcSource.right = 0; | |
135 //this->m_sVhdr->rcSource.bottom = 0; | |
136 this->m_sVhdr->rcTarget = this->m_sVhdr->rcSource; | |
1545 | 137 |
3059 | 138 this->m_sOurType.majortype = MEDIATYPE_Video; |
139 this->m_sOurType.subtype = MEDIATYPE_Video; | |
140 this->m_sOurType.subtype.f1 = this->m_sVhdr->bmiHeader.biCompression; | |
141 this->m_sOurType.formattype = FORMAT_VideoInfo; | |
142 this->m_sOurType.bFixedSizeSamples = false; | |
143 this->m_sOurType.bTemporalCompression = true; | |
144 this->m_sOurType.pUnk = 0; | |
145 this->m_sOurType.cbFormat = bihs; | |
146 this->m_sOurType.pbFormat = (char*)this->m_sVhdr; | |
147 | |
148 this->m_sVhdr2 = (VIDEOINFOHEADER*)(malloc(sizeof(VIDEOINFOHEADER)+12)); | |
149 memcpy(this->m_sVhdr2, this->m_sVhdr, sizeof(VIDEOINFOHEADER)); | |
150 memset((char*)this->m_sVhdr2 + sizeof(VIDEOINFOHEADER), 0, 12); | |
151 this->m_sVhdr2->bmiHeader.biCompression = 0; | |
152 this->m_sVhdr2->bmiHeader.biBitCount = 24; | |
1545 | 153 |
3059 | 154 memset(&this->m_sDestType, 0, sizeof(this->m_sDestType)); |
155 this->m_sDestType.majortype = MEDIATYPE_Video; | |
156 this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; | |
157 this->m_sDestType.formattype = FORMAT_VideoInfo; | |
158 this->m_sDestType.bFixedSizeSamples = true; | |
159 this->m_sDestType.bTemporalCompression = false; | |
160 this->m_sDestType.lSampleSize = labs(this->m_sVhdr2->bmiHeader.biWidth*this->m_sVhdr2->bmiHeader.biHeight | |
161 * ((this->m_sVhdr2->bmiHeader.biBitCount + 7) / 8)); | |
162 this->m_sVhdr2->bmiHeader.biSizeImage = this->m_sDestType.lSampleSize; | |
163 this->m_sDestType.pUnk = 0; | |
164 this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); | |
165 this->m_sDestType.pbFormat = (char*)this->m_sVhdr2; | |
166 | |
167 memset(&this->iv.m_obh, 0, sizeof(this->iv.m_obh)); | |
168 memcpy(&this->iv.m_obh, this->iv.m_bh, sizeof(this->iv.m_obh) < (unsigned) this->iv.m_bh->biSize | |
169 ? sizeof(this->iv.m_obh) : (unsigned) this->iv.m_bh->biSize); | |
170 this->iv.m_obh.biBitCount=24; | |
171 this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); | |
172 this->iv.m_obh.biCompression = 0; //BI_RGB | |
173 //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight); | |
174 this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight) | |
175 * ((this->iv.m_obh.biBitCount + 7) / 8); | |
1545 | 176 |
177 | |
3444 | 178 this->m_pDS_Filter = DS_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); |
3456 | 179 |
180 if (!this->m_pDS_Filter) | |
181 { | |
182 printf("Failed to create DirectShow filter\n"); | |
183 return 0; | |
184 } | |
1545 | 185 |
186 if (!flip) | |
187 { | |
3059 | 188 this->iv.m_obh.biHeight *= -1; |
3466 | 189 this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; |
3059 | 190 result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType); |
1545 | 191 if (result) |
192 { | |
3466 | 193 printf("Decoder does not support upside-down RGB frames\n"); |
3059 | 194 this->iv.m_obh.biHeight *= -1; |
3466 | 195 this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; |
1545 | 196 } |
197 } | |
198 | |
3059 | 199 memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh) ); |
1545 | 200 |
3059 | 201 switch (this->iv.m_bh->biCompression) |
1545 | 202 { |
6527 | 203 #if 0 |
1545 | 204 case fccDIV3: |
205 case fccDIV4: | |
206 case fccDIV5: | |
3059 | 207 case fccDIV6: |
1545 | 208 case fccMP42: |
209 case fccWMV2: | |
210 //YV12 seems to be broken for DivX :-) codec | |
3060 | 211 // case fccIV50: |
1545 | 212 //produces incorrect picture |
213 //m_Caps = (CAPS) (m_Caps & ~CAP_YV12); | |
3059 | 214 //m_Caps = CAP_UYVY;//CAP_YUY2; // | CAP_I420; |
215 //m_Caps = CAP_I420; | |
216 this->m_Caps = (CAP_YUY2 | CAP_UYVY); | |
1545 | 217 break; |
6527 | 218 #endif |
1545 | 219 default: |
3059 | 220 |
221 this->m_Caps = CAP_NONE; | |
1545 | 222 |
6527 | 223 printf("Decoder supports the following YUV formats: "); |
3059 | 224 for (c = check; c->bits; c++) |
1545 | 225 { |
3059 | 226 this->m_sVhdr2->bmiHeader.biBitCount = c->bits; |
227 this->m_sVhdr2->bmiHeader.biCompression = c->fcc; | |
228 this->m_sDestType.subtype = *c->subtype; | |
229 result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType); | |
1545 | 230 if (!result) |
6527 | 231 { |
3059 | 232 this->m_Caps = (this->m_Caps | c->cap); |
8451 | 233 printf("%.4s ", (char *)&c->fcc); |
6527 | 234 } |
1545 | 235 } |
6527 | 236 printf("\n"); |
1545 | 237 } |
238 | |
3059 | 239 if (this->m_Caps != CAP_NONE) |
6527 | 240 printf("Decoder is capable of YUV output (flags 0x%x)\n", (int)this->m_Caps); |
1545 | 241 |
3059 | 242 this->m_sVhdr2->bmiHeader.biBitCount = 24; |
243 this->m_sVhdr2->bmiHeader.biCompression = 0; | |
244 this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; | |
1545 | 245 |
3059 | 246 this->m_iMinBuffers = this->iv.VBUFSIZE; |
3444 | 247 this->m_bIsDivX = (strcmp(dllname, "divxcvki.ax") == 0 |
248 || strcmp(dllname, "divx_c32.ax") == 0 | |
249 || strcmp(dllname, "wmvds32.ax") == 0 | |
250 || strcmp(dllname, "wmv8ds32.ax") == 0); | |
251 this->m_bIsDivX4 = (strcmp(dllname, "divxdec.ax") == 0); | |
3059 | 252 if (this->m_bIsDivX) |
253 this->iv.VBUFSIZE += 7; | |
254 else if (this->m_bIsDivX4) | |
255 this->iv.VBUFSIZE += 9; | |
1545 | 256 } |
3059 | 257 /*catch (FatalError& error) |
1545 | 258 { |
3059 | 259 delete[] m_sVhdr; |
1545 | 260 delete[] m_sVhdr2; |
261 delete m_pDS_Filter; | |
262 throw; | |
3059 | 263 }*/ |
264 return this; | |
1545 | 265 } |
266 | |
3059 | 267 void DS_VideoDecoder_Destroy(DS_VideoDecoder *this) |
1545 | 268 { |
3059 | 269 DS_VideoDecoder_StopInternal(this); |
270 this->iv.m_State = STOP; | |
271 free(this->m_sVhdr); | |
272 free(this->m_sVhdr2); | |
273 DS_Filter_Destroy(this->m_pDS_Filter); | |
1545 | 274 } |
275 | |
3059 | 276 void DS_VideoDecoder_StartInternal(DS_VideoDecoder *this) |
1545 | 277 { |
3059 | 278 ALLOCATOR_PROPERTIES props, props1; |
279 Debug printf("DS_VideoDecoder_StartInternal\n"); | |
1545 | 280 //cout << "DSSTART" << endl; |
3063 | 281 this->m_pDS_Filter->Start(this->m_pDS_Filter); |
3059 | 282 |
1545 | 283 props.cBuffers = 1; |
3059 | 284 props.cbBuffer = this->m_sDestType.lSampleSize; |
9503
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8451
diff
changeset
|
285 props.cbAlign = 1; |
f47d484d8f28
cbAlign=1 fix for proper Windows support (noticed by Sascha Sommer)
alex
parents:
8451
diff
changeset
|
286 props.cbPrefix = 0; |
3059 | 287 this->m_pDS_Filter->m_pAll->vt->SetProperties(this->m_pDS_Filter->m_pAll, &props, &props1); |
288 this->m_pDS_Filter->m_pAll->vt->Commit(this->m_pDS_Filter->m_pAll); | |
289 | |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
290 this->iv.m_State = START; |
1545 | 291 } |
292 | |
3059 | 293 void DS_VideoDecoder_StopInternal(DS_VideoDecoder *this) |
1545 | 294 { |
3063 | 295 this->m_pDS_Filter->Stop(this->m_pDS_Filter); |
1545 | 296 //??? why was this here ??? m_pOurOutput->SetFramePointer(0); |
297 } | |
298 | |
3063 | 299 int DS_VideoDecoder_DecodeInternal(DS_VideoDecoder *this, const void* src, int size, int is_keyframe, char* pImage) |
1545 | 300 { |
301 IMediaSample* sample = 0; | |
3059 | 302 char* ptr; |
303 int result; | |
304 | |
3063 | 305 Debug printf("DS_VideoDecoder_DecodeInternal(%p,%p,%d,%d,%p)\n",this,src,size,is_keyframe,pImage); |
3059 | 306 |
307 this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0); | |
308 | |
1545 | 309 if (!sample) |
310 { | |
3059 | 311 Debug printf("ERROR: null sample\n"); |
1545 | 312 return -1; |
313 } | |
3059 | 314 |
1545 | 315 //cout << "DECODE " << (void*) pImage << " d: " << (void*) pImage->Data() << endl; |
316 if (pImage) | |
317 { | |
3063 | 318 this->m_pDS_Filter->m_pOurOutput->SetPointer2(this->m_pDS_Filter->m_pOurOutput,pImage); |
1545 | 319 } |
320 | |
3059 | 321 |
3466 | 322 sample->vt->SetActualDataLength(sample, size); |
1545 | 323 sample->vt->GetPointer(sample, (BYTE **)&ptr); |
324 memcpy(ptr, src, size); | |
325 sample->vt->SetSyncPoint(sample, is_keyframe); | |
326 sample->vt->SetPreroll(sample, pImage ? 0 : 1); | |
327 // sample->vt->SetMediaType(sample, &m_sOurType); | |
328 | |
329 // FIXME: - crashing with YV12 at this place decoder will crash | |
330 // while doing this call | |
331 // %FS register was not setup for calling into win32 dll. Are all | |
332 // crashes inside ...->Receive() fixed now? | |
333 // | |
334 // nope - but this is surely helpfull - I'll try some more experiments | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9581
diff
changeset
|
335 #ifdef WIN32_LOADER |
3060 | 336 Setup_FS_Segment(); |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
9581
diff
changeset
|
337 #endif |
1545 | 338 #if 0 |
3059 | 339 if (!this->m_pDS_Filter || !this->m_pDS_Filter->m_pImp |
340 || !this->m_pDS_Filter->m_pImp->vt | |
341 || !this->m_pDS_Filter->m_pImp->vt->Receive) | |
1545 | 342 printf("DecodeInternal ERROR???\n"); |
343 #endif | |
3059 | 344 result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample); |
1545 | 345 if (result) |
346 { | |
347 Debug printf("DS_VideoDecoder::DecodeInternal() error putting data into input pin %x\n", result); | |
348 } | |
349 | |
350 sample->vt->Release((IUnknown*)sample); | |
351 | |
3059 | 352 #if 0 |
353 if (this->m_bIsDivX) | |
1545 | 354 { |
355 int q; | |
3059 | 356 IHidden* hidden=(IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8); |
1545 | 357 // always check for actual value |
358 // this seems to be the only way to know the actual value | |
3059 | 359 hidden->vt->GetSmth2(hidden, &this->m_iLastQuality); |
360 if (this->m_iLastQuality > 9) | |
361 this->m_iLastQuality -= 10; | |
362 | |
363 if (this->m_iLastQuality < 0) | |
364 this->m_iLastQuality = 0; | |
365 else if (this->m_iLastQuality > this->m_iMaxAuto) | |
366 this->m_iLastQuality = this->m_iMaxAuto; | |
1545 | 367 |
3059 | 368 //cout << " Qual: " << this->m_iLastQuality << endl; |
369 this->iv.m_fQuality = this->m_iLastQuality / 4.0; | |
370 } | |
371 else if (this->m_bIsDivX4) | |
372 { | |
373 | |
374 // maybe access methods directly to safe some cpu cycles... | |
375 DS_VideoDecoder_GetValue(this, "Postprocessing", this->m_iLastQuality); | |
376 if (this->m_iLastQuality < 0) | |
377 this->m_iLastQuality = 0; | |
378 else if (this->m_iLastQuality > this->m_iMaxAuto) | |
379 this->m_iLastQuality = this->m_iMaxAuto; | |
1545 | 380 |
381 //cout << " Qual: " << m_iLastQuality << endl; | |
3059 | 382 this->iv.m_fQuality = this->m_iLastQuality / 6.0; |
1545 | 383 } |
384 | |
3059 | 385 if (this->iv.m_Mode == -1 ) // ???BUFFERED_QUALITY_AUTO) |
1545 | 386 { |
387 // adjust Quality - depends on how many cached frames we have | |
3059 | 388 int buffered = this->iv.m_iDecpos - this->iv.m_iPlaypos; |
1545 | 389 |
3059 | 390 if (this->m_bIsDivX || this->m_bIsDivX4) |
391 { | |
392 int to = buffered - this->m_iMinBuffers; | |
393 if (to < 0) | |
394 to = 0; | |
395 if (to != this->m_iLastQuality) | |
396 { | |
397 if (to > this->m_iMaxAuto) | |
398 to = this->m_iMaxAuto; | |
399 if (this->m_iLastQuality != to) | |
1545 | 400 { |
3059 | 401 if (this->m_bIsDivX) |
402 { | |
403 IHidden* hidden=(IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8); | |
404 hidden->vt->SetSmth(hidden, to, 0); | |
405 } | |
406 else | |
407 DS_VideoDecoder_SetValue(this, "Postprocessing", to); | |
1545 | 408 #ifndef QUIET |
3059 | 409 //printf("Switching quality %d -> %d b:%d\n",m_iLastQuality, to, buffered); |
1545 | 410 #endif |
411 } | |
412 } | |
413 } | |
414 } | |
3059 | 415 #endif |
1545 | 416 |
417 return 0; | |
418 } | |
419 | |
420 /* | |
421 * bits == 0 - leave unchanged | |
422 */ | |
3059 | 423 //int SetDestFmt(DS_VideoDecoder * this, int bits = 24, fourcc_t csp = 0); |
3946 | 424 int DS_VideoDecoder_SetDestFmt(DS_VideoDecoder *this, int bits, unsigned int csp) |
1545 | 425 { |
3059 | 426 HRESULT result; |
427 int should_test=1; | |
428 int stoped = 0; | |
429 | |
430 Debug printf("DS_VideoDecoder_SetDestFmt (%p, %d, %d)\n",this,bits,(int)csp); | |
431 | |
432 /* if (!CImage::Supported(csp, bits)) | |
1545 | 433 return -1; |
3059 | 434 */ |
1545 | 435 // BitmapInfo temp = m_obh; |
3059 | 436 |
3063 | 437 if (!csp) // RGB |
1545 | 438 { |
3059 | 439 int ok = true; |
1545 | 440 |
441 switch (bits) | |
442 { | |
443 case 15: | |
3059 | 444 this->m_sDestType.subtype = MEDIASUBTYPE_RGB555; |
1545 | 445 break; |
446 case 16: | |
3059 | 447 this->m_sDestType.subtype = MEDIASUBTYPE_RGB565; |
1545 | 448 break; |
449 case 24: | |
3059 | 450 this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; |
1545 | 451 break; |
452 case 32: | |
3059 | 453 this->m_sDestType.subtype = MEDIASUBTYPE_RGB32; |
1545 | 454 break; |
455 default: | |
456 ok = false; | |
457 break; | |
458 } | |
459 | |
3059 | 460 if (ok) { |
9581 | 461 if (bits == 15) |
462 this->iv.m_obh.biBitCount=16; | |
463 else | |
464 this->iv.m_obh.biBitCount=bits; | |
3059 | 465 if( bits == 15 || bits == 16 ) { |
466 this->iv.m_obh.biSize=sizeof(BITMAPINFOHEADER)+12; | |
467 this->iv.m_obh.biCompression=3;//BI_BITFIELDS | |
468 this->iv.m_obh.biSizeImage=abs((int)(2*this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)); | |
469 } | |
470 | |
471 if( bits == 16 ) { | |
472 this->iv.m_obh.colors[0]=0xF800; | |
473 this->iv.m_obh.colors[1]=0x07E0; | |
474 this->iv.m_obh.colors[2]=0x001F; | |
475 } else if ( bits == 15 ) { | |
476 this->iv.m_obh.colors[0]=0x7C00; | |
477 this->iv.m_obh.colors[1]=0x03E0; | |
478 this->iv.m_obh.colors[2]=0x001F; | |
479 } else { | |
480 this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); | |
481 this->iv.m_obh.biCompression = 0; //BI_RGB | |
482 //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight); | |
483 this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight) | |
484 * ((this->iv.m_obh.biBitCount + 7) / 8); | |
485 } | |
486 } | |
1545 | 487 //.biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8)); |
3063 | 488 } else |
489 { // YUV | |
3059 | 490 int ok = true; |
1545 | 491 switch (csp) |
492 { | |
493 case fccYUY2: | |
3059 | 494 this->m_sDestType.subtype = MEDIASUBTYPE_YUY2; |
1545 | 495 break; |
496 case fccYV12: | |
3059 | 497 this->m_sDestType.subtype = MEDIASUBTYPE_YV12; |
1545 | 498 break; |
499 case fccIYUV: | |
3059 | 500 this->m_sDestType.subtype = MEDIASUBTYPE_IYUV; |
1545 | 501 break; |
6527 | 502 case fccI420: |
503 this->m_sDestType.subtype = MEDIASUBTYPE_I420; | |
504 break; | |
1545 | 505 case fccUYVY: |
3059 | 506 this->m_sDestType.subtype = MEDIASUBTYPE_UYVY; |
1545 | 507 break; |
508 case fccYVYU: | |
3059 | 509 this->m_sDestType.subtype = MEDIASUBTYPE_YVYU; |
1545 | 510 break; |
6527 | 511 case fccYVU9: |
512 this->m_sDestType.subtype = MEDIASUBTYPE_YVU9; | |
1545 | 513 default: |
514 ok = false; | |
515 break; | |
516 } | |
517 | |
3059 | 518 if (ok) { |
519 if (csp != 0 && csp != 3 && this->iv.m_obh.biHeight > 0) | |
520 this->iv.m_obh.biHeight *= -1; // YUV formats uses should have height < 0 | |
521 this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); | |
522 this->iv.m_obh.biCompression=csp; | |
523 this->iv.m_obh.biBitCount=bits; | |
524 this->iv.m_obh.biSizeImage=labs(this->iv.m_obh.biBitCount* | |
525 this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)>>3; | |
526 } | |
1545 | 527 } |
3059 | 528 this->m_sDestType.lSampleSize = this->iv.m_obh.biSizeImage; |
529 memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_obh, sizeof(this->iv.m_obh)); | |
530 this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
531 if (this->m_sVhdr2->bmiHeader.biCompression == 3) | |
532 this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; | |
1545 | 533 else |
3059 | 534 this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); |
1545 | 535 |
3059 | 536 |
1545 | 537 switch(csp) |
538 { | |
539 case fccYUY2: | |
3059 | 540 if(!(this->m_Caps & CAP_YUY2)) |
1545 | 541 should_test=false; |
542 break; | |
543 case fccYV12: | |
3059 | 544 if(!(this->m_Caps & CAP_YV12)) |
1545 | 545 should_test=false; |
546 break; | |
547 case fccIYUV: | |
3059 | 548 if(!(this->m_Caps & CAP_IYUV)) |
1545 | 549 should_test=false; |
550 break; | |
6527 | 551 case fccI420: |
552 if(!(this->m_Caps & CAP_I420)) | |
553 should_test=false; | |
554 break; | |
1545 | 555 case fccUYVY: |
3059 | 556 if(!(this->m_Caps & CAP_UYVY)) |
1545 | 557 should_test=false; |
558 break; | |
559 case fccYVYU: | |
3059 | 560 if(!(this->m_Caps & CAP_YVYU)) |
1545 | 561 should_test=false; |
562 break; | |
6527 | 563 case fccYVU9: |
564 if(!(this->m_Caps & CAP_YVU9)) | |
565 should_test=false; | |
566 break; | |
1545 | 567 } |
568 if(should_test) | |
3059 | 569 result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType); |
1545 | 570 else |
571 result = -1; | |
572 | |
573 if (result != 0) | |
574 { | |
575 if (csp) | |
3059 | 576 printf("Warning: unsupported color space\n"); |
1545 | 577 else |
3059 | 578 printf("Warning: unsupported bit depth\n"); |
1545 | 579 |
3059 | 580 this->m_sDestType.lSampleSize = this->iv.m_decoder.biSizeImage; |
581 memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_decoder, sizeof(this->iv.m_decoder)); | |
582 this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
583 if (this->m_sVhdr2->bmiHeader.biCompression == 3) | |
584 this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; | |
1545 | 585 else |
3059 | 586 this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); |
1545 | 587 |
3059 | 588 return -1; |
1545 | 589 } |
590 | |
3059 | 591 memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh)); |
1545 | 592 |
593 // m_obh=temp; | |
594 // if(csp) | |
595 // m_obh.biBitCount=BitmapInfo::BitCount(csp); | |
3059 | 596 this->iv.m_bh->biBitCount = bits; |
597 | |
598 //DS_VideoDecoder_Restart(this); | |
1545 | 599 |
3059 | 600 if (this->iv.m_State == START) |
1545 | 601 { |
3059 | 602 DS_VideoDecoder_StopInternal(this); |
603 this->iv.m_State = STOP; | |
1545 | 604 stoped = true; |
605 } | |
606 | |
3059 | 607 this->m_pDS_Filter->m_pInputPin->vt->Disconnect(this->m_pDS_Filter->m_pInputPin); |
608 this->m_pDS_Filter->m_pOutputPin->vt->Disconnect(this->m_pDS_Filter->m_pOutputPin); | |
3063 | 609 this->m_pDS_Filter->m_pOurOutput->SetNewFormat(this->m_pDS_Filter->m_pOurOutput,&this->m_sDestType); |
3059 | 610 result = this->m_pDS_Filter->m_pInputPin->vt->ReceiveConnection(this->m_pDS_Filter->m_pInputPin, |
611 this->m_pDS_Filter->m_pOurInput, | |
612 &this->m_sOurType); | |
1545 | 613 if (result) |
614 { | |
3059 | 615 printf("Error reconnecting input pin 0x%x\n", (int)result); |
1545 | 616 return -1; |
617 } | |
3059 | 618 result = this->m_pDS_Filter->m_pOutputPin->vt->ReceiveConnection(this->m_pDS_Filter->m_pOutputPin, |
619 (IPin *)this->m_pDS_Filter->m_pOurOutput, | |
620 &this->m_sDestType); | |
1545 | 621 if (result) |
622 { | |
3059 | 623 printf("Error reconnecting output pin 0x%x\n", (int)result); |
1545 | 624 return -1; |
625 } | |
626 | |
627 if (stoped) | |
3059 | 628 { |
629 DS_VideoDecoder_StartInternal(this); | |
630 this->iv.m_State = START; | |
631 } | |
1545 | 632 |
633 return 0; | |
634 } | |
635 | |
3059 | 636 |
637 int DS_VideoDecoder_SetDirection(DS_VideoDecoder *this, int d) | |
638 { | |
639 this->iv.m_obh.biHeight = (d) ? this->iv.m_bh->biHeight : -this->iv.m_bh->biHeight; | |
640 this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; | |
641 return 0; | |
642 } | |
643 | |
3946 | 644 int DS_VideoDecoder_GetValue(DS_VideoDecoder *this, const char* name, int* value) |
1545 | 645 { |
3059 | 646 /* |
647 if (m_bIsDivX4) | |
648 { | |
649 IDivxFilterInterface* pIDivx; | |
650 if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_IDivxFilterInterface, (void**)&pIDivx)) | |
651 { | |
652 Debug printf("No such interface\n"); | |
653 return -1; | |
654 } | |
655 if (strcmp(name, "Postprocessing") == 0) | |
656 { | |
657 pIDivx->vt->get_PPLevel(pIDivx, &value); | |
658 value /= 10; | |
659 } | |
660 else if (strcmp(name, "Brightness") == 0) | |
661 pIDivx->vt->get_Brightness(pIDivx, &value); | |
662 else if (strcmp(name, "Contrast") == 0) | |
663 pIDivx->vt->get_Contrast(pIDivx, &value); | |
664 else if (strcmp(name, "Saturation") == 0) | |
665 pIDivx->vt->get_Saturation(pIDivx, &value); | |
666 else if (strcmp(name, "MaxAuto") == 0) | |
667 value = m_iMaxAuto; | |
668 pIDivx->vt->Release((IUnknown*)pIDivx); | |
669 return 0; | |
670 } | |
671 else if (m_bIsDivX) | |
1545 | 672 { |
673 if (m_State != START) | |
674 return VFW_E_NOT_RUNNING; | |
675 // brightness 87 | |
676 // contrast 74 | |
677 // hue 23 | |
678 // saturation 20 | |
679 // post process mode 0 | |
680 // get1 0x01 | |
681 // get2 10 | |
682 // get3=set2 86 | |
683 // get4=set3 73 | |
684 // get5=set4 19 | |
685 // get6=set5 23 | |
686 IHidden* hidden=(IHidden*)((int)m_pDS_Filter->m_pFilter+0xb8); | |
3059 | 687 if (strcmp(name, "Quality") == 0) |
688 { | |
689 #warning NOT SURE | |
690 int r = hidden->vt->GetSmth2(hidden, &value); | |
691 if (value >= 10) | |
692 value -= 10; | |
693 return 0; | |
694 } | |
1545 | 695 if (strcmp(name, "Brightness") == 0) |
696 return hidden->vt->GetSmth3(hidden, &value); | |
697 if (strcmp(name, "Contrast") == 0) | |
698 return hidden->vt->GetSmth4(hidden, &value); | |
699 if (strcmp(name, "Hue") == 0) | |
700 return hidden->vt->GetSmth6(hidden, &value); | |
701 if (strcmp(name, "Saturation") == 0) | |
702 return hidden->vt->GetSmth5(hidden, &value); | |
3059 | 703 if (strcmp(name, "MaxAuto") == 0) |
1545 | 704 { |
3059 | 705 value = m_iMaxAuto; |
706 return 0; | |
1545 | 707 } |
708 } | |
3059 | 709 else if (strcmp((const char*)record.dll, "ir50_32.dll") == 0) |
1545 | 710 { |
711 IHidden2* hidden = 0; | |
712 if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden)) | |
713 { | |
3059 | 714 Debug printf("No such interface\n"); |
1545 | 715 return -1; |
716 } | |
717 #warning FIXME | |
718 int recordpar[30]; | |
719 recordpar[0]=0x7c; | |
720 recordpar[1]=fccIV50; | |
721 recordpar[2]=0x10005; | |
722 recordpar[3]=2; | |
723 recordpar[4]=1; | |
724 recordpar[5]=0x80000000; | |
725 | |
726 if (strcmp(name, "Brightness") == 0) | |
727 recordpar[5]|=0x20; | |
728 else if (strcmp(name, "Saturation") == 0) | |
729 recordpar[5]|=0x40; | |
730 else if (strcmp(name, "Contrast") == 0) | |
731 recordpar[5]|=0x80; | |
732 if (!recordpar[5]) | |
733 { | |
734 hidden->vt->Release((IUnknown*)hidden); | |
735 return -1; | |
736 } | |
737 if (hidden->vt->DecodeSet(hidden, recordpar)) | |
738 return -1; | |
739 | |
740 if (strcmp(name, "Brightness") == 0) | |
741 value = recordpar[18]; | |
742 else if (strcmp(name, "Saturation") == 0) | |
743 value = recordpar[19]; | |
744 else if (strcmp(name, "Contrast") == 0) | |
745 value = recordpar[20]; | |
746 | |
747 hidden->vt->Release((IUnknown*)hidden); | |
748 } | |
3059 | 749 */ |
1545 | 750 return 0; |
751 } | |
752 | |
3946 | 753 int DS_VideoDecoder_SetValue(DS_VideoDecoder *this, const char* name, int value) |
1545 | 754 { |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
755 if (this->m_bIsDivX4) { |
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
756 IDivxFilterInterface* pIDivx=NULL; |
3978 | 757 // printf("DS_SetValue for DIVX4, name=%s value=%d\n",name,value); |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
758 if (this->m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)this->m_pDS_Filter->m_pFilter, &IID_IDivxFilterInterface, (void**)&pIDivx)) |
3059 | 759 { |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
760 printf("No such interface\n"); |
3059 | 761 return -1; |
762 } | |
6801 | 763 if (strcasecmp(name, "Postprocessing") == 0) |
3059 | 764 pIDivx->vt->put_PPLevel(pIDivx, value * 10); |
6801 | 765 else if (strcasecmp(name, "Brightness") == 0) |
3059 | 766 pIDivx->vt->put_Brightness(pIDivx, value); |
6801 | 767 else if (strcasecmp(name, "Contrast") == 0) |
3059 | 768 pIDivx->vt->put_Contrast(pIDivx, value); |
6801 | 769 else if (strcasecmp(name, "Saturation") == 0) |
3059 | 770 pIDivx->vt->put_Saturation(pIDivx, value); |
6801 | 771 else if (strcasecmp(name, "MaxAuto") == 0) |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
772 this->m_iMaxAuto = value; |
3059 | 773 pIDivx->vt->Release((IUnknown*)pIDivx); |
774 //printf("Set %s %d\n", name, value); | |
775 return 0; | |
776 } | |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
777 |
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
778 if (this->m_bIsDivX) { |
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
779 IHidden* hidden; |
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
780 if (this->iv.m_State != START) |
1545 | 781 return VFW_E_NOT_RUNNING; |
782 | |
783 //cout << "set value " << name << " " << value << endl; | |
784 // brightness 87 | |
785 // contrast 74 | |
786 // hue 23 | |
787 // saturation 20 | |
788 // post process mode 0 | |
789 // get1 0x01 | |
790 // get2 10 | |
791 // get3=set2 86 | |
792 // get4=set3 73 | |
793 // get5=set4 19 | |
3059 | 794 // get6=set5 23 |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
795 hidden = (IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8); |
7316 | 796 //printf("DS_SetValue for DIVX, name=%s value=%d\n",name,value); |
6801 | 797 if (strcasecmp(name, "Quality") == 0) |
1545 | 798 { |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
799 this->m_iLastQuality = value; |
1545 | 800 return hidden->vt->SetSmth(hidden, value, 0); |
801 } | |
6801 | 802 if (strcasecmp(name, "Brightness") == 0) |
1545 | 803 return hidden->vt->SetSmth2(hidden, value, 0); |
6801 | 804 if (strcasecmp(name, "Contrast") == 0) |
1545 | 805 return hidden->vt->SetSmth3(hidden, value, 0); |
6801 | 806 if (strcasecmp(name, "Saturation") == 0) |
1545 | 807 return hidden->vt->SetSmth4(hidden, value, 0); |
6801 | 808 if (strcasecmp(name, "Hue") == 0) |
1545 | 809 return hidden->vt->SetSmth5(hidden, value, 0); |
6801 | 810 if (strcasecmp(name, "MaxAuto") == 0) |
3059 | 811 { |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
812 this->m_iMaxAuto = value; |
3059 | 813 } |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
814 return 0; |
1545 | 815 } |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
816 #if 0 |
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
817 if (strcmp((const char*)record.dll, "ir50_32.dll") == 0) |
1545 | 818 { |
819 IHidden2* hidden = 0; | |
820 if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden)) | |
821 { | |
3059 | 822 Debug printf("No such interface\n"); |
1545 | 823 return -1; |
824 } | |
825 int recordpar[30]; | |
826 recordpar[0]=0x7c; | |
827 recordpar[1]=fccIV50; | |
828 recordpar[2]=0x10005; | |
829 recordpar[3]=2; | |
830 recordpar[4]=1; | |
831 recordpar[5]=0x80000000; | |
832 if (strcmp(name, "Brightness") == 0) | |
833 { | |
834 recordpar[5]|=0x20; | |
835 recordpar[18]=value; | |
836 } | |
837 else if (strcmp(name, "Saturation") == 0) | |
838 { | |
839 recordpar[5]|=0x40; | |
840 recordpar[19]=value; | |
841 } | |
842 else if (strcmp(name, "Contrast") == 0) | |
843 { | |
844 recordpar[5]|=0x80; | |
845 recordpar[20]=value; | |
846 } | |
847 if(!recordpar[5]) | |
848 { | |
849 hidden->vt->Release((IUnknown*)hidden); | |
850 return -1; | |
851 } | |
852 HRESULT result = hidden->vt->DecodeSet(hidden, recordpar); | |
853 hidden->vt->Release((IUnknown*)hidden); | |
854 | |
855 return result; | |
856 } | |
3957
49290522ab06
SetValue fixed, iv_State=START enabled (silly xine developers disabled for unknown reason)
arpi
parents:
3946
diff
changeset
|
857 #endif |
3978 | 858 // printf("DS_SetValue for ????, name=%s value=%d\n",name,value); |
1545 | 859 return 0; |
860 } | |
861 /* | |
3063 | 862 vim: vi* sux. |
1545 | 863 */ |
3063 | 864 |
865 int DS_SetAttr_DivX(char* attribute, int value){ | |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
7316
diff
changeset
|
866 int result, status, newkey; |
6801 | 867 if(strcasecmp(attribute, "Quality")==0){ |
3063 | 868 char* keyname="SOFTWARE\\Microsoft\\Scrunch"; |
869 result=RegCreateKeyExA(HKEY_CURRENT_USER, keyname, 0, 0, 0, 0, 0, &newkey, &status); | |
870 if(result!=0) | |
871 { | |
872 printf("VideoDecoder::SetExtAttr: registry failure\n"); | |
873 return -1; | |
874 } | |
875 result=RegSetValueExA(newkey, "Current Post Process Mode", 0, REG_DWORD, &value, 4); | |
876 if(result!=0) | |
877 { | |
878 printf("VideoDecoder::SetExtAttr: error writing value\n"); | |
879 return -1; | |
880 } | |
881 value=-1; | |
882 result=RegSetValueExA(newkey, "Force Post Process Mode", 0, REG_DWORD, &value, 4); | |
883 if(result!=0) | |
884 { | |
885 printf("VideoDecoder::SetExtAttr: error writing value\n"); | |
886 return -1; | |
887 } | |
888 RegCloseKey(newkey); | |
889 return 0; | |
890 } | |
891 | |
892 if( | |
6801 | 893 (strcasecmp(attribute, "Saturation")==0) || |
894 (strcasecmp(attribute, "Hue")==0) || | |
895 (strcasecmp(attribute, "Contrast")==0) || | |
896 (strcasecmp(attribute, "Brightness")==0) | |
3063 | 897 ) |
898 { | |
899 char* keyname="SOFTWARE\\Microsoft\\Scrunch\\Video"; | |
900 result=RegCreateKeyExA(HKEY_CURRENT_USER, keyname, 0, 0, 0, 0, 0, &newkey, &status); | |
901 if(result!=0) | |
902 { | |
903 printf("VideoDecoder::SetExtAttr: registry failure\n"); | |
904 return -1; | |
905 } | |
906 result=RegSetValueExA(newkey, attribute, 0, REG_DWORD, &value, 4); | |
907 if(result!=0) | |
908 { | |
909 printf("VideoDecoder::SetExtAttr: error writing value\n"); | |
910 return -1; | |
911 } | |
912 RegCloseKey(newkey); | |
913 return 0; | |
914 } | |
915 | |
916 printf("Unknown attribute!\n"); | |
917 return -200; | |
918 } | |
919 | |
920 | |
921 | |
922 |