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