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