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