19 |
* along with this program ; if not, write to the Free Software |
* along with this program ; if not, write to the Free Software |
20 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 |
* |
* |
22 |
* $Id: CXvidDecoder.cpp,v 1.11 2004-07-25 11:13:16 suxen_drol Exp $ |
* $Id: CXvidDecoder.cpp,v 1.18 2010-08-10 14:17:40 Isibaar Exp $ |
23 |
* |
* |
24 |
****************************************************************************/ |
****************************************************************************/ |
25 |
|
|
82 |
{ &MEDIATYPE_Video, &CLSID_DX50 }, |
{ &MEDIATYPE_Video, &CLSID_DX50 }, |
83 |
{ &MEDIATYPE_Video, &CLSID_DX50_UC }, |
{ &MEDIATYPE_Video, &CLSID_DX50_UC }, |
84 |
{ &MEDIATYPE_Video, &CLSID_MP4V }, |
{ &MEDIATYPE_Video, &CLSID_MP4V }, |
85 |
|
{ &MEDIATYPE_Video, &CLSID_MP4V_UC }, |
86 |
}; |
}; |
87 |
|
|
88 |
const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] = |
const AMOVIESETUP_MEDIATYPE sudOutputPinTypes[] = |
205 |
#define XVID_DLL_NAME "xvidcore.dll" |
#define XVID_DLL_NAME "xvidcore.dll" |
206 |
|
|
207 |
CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) : |
CXvidDecoder::CXvidDecoder(LPUNKNOWN punk, HRESULT *phr) : |
208 |
CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID) |
CVideoTransformFilter(NAME("CXvidDecoder"), punk, CLSID_XVID), m_hdll (NULL) |
209 |
{ |
{ |
210 |
DPRINTF("Constructor"); |
DPRINTF("Constructor"); |
211 |
|
|
212 |
|
xvid_decore_func = NULL; // Hmm, some strange errors appearing if I try to initialize... |
213 |
|
xvid_global_func = NULL; // ...this in constructor's init-list. So, they assigned here. |
214 |
|
|
215 |
|
LoadRegistryInfo(); |
216 |
|
|
217 |
|
*phr = OpenLib(); |
218 |
|
} |
219 |
|
|
220 |
|
HRESULT CXvidDecoder::OpenLib() |
221 |
|
{ |
222 |
|
DPRINTF("OpenLib"); |
223 |
|
|
224 |
|
if (m_hdll != NULL) |
225 |
|
return E_UNEXPECTED; // Seems, that library already opened. |
226 |
|
|
227 |
xvid_gbl_init_t init; |
xvid_gbl_init_t init; |
228 |
memset(&init, 0, sizeof(init)); |
memset(&init, 0, sizeof(init)); |
229 |
init.version = XVID_VERSION; |
init.version = XVID_VERSION; |
232 |
if (m_hdll == NULL) { |
if (m_hdll == NULL) { |
233 |
DPRINTF("dll load failed"); |
DPRINTF("dll load failed"); |
234 |
MessageBox(0, XVID_DLL_NAME " not found","Error", MB_TOPMOST); |
MessageBox(0, XVID_DLL_NAME " not found","Error", MB_TOPMOST); |
235 |
return; |
return E_FAIL; |
236 |
} |
} |
237 |
|
|
238 |
xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global"); |
xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global"); |
239 |
if (xvid_global_func == NULL) { |
if (xvid_global_func == NULL) { |
240 |
|
FreeLibrary(m_hdll); |
241 |
|
m_hdll = NULL; |
242 |
MessageBox(0, "xvid_global() not found", "Error", MB_TOPMOST); |
MessageBox(0, "xvid_global() not found", "Error", MB_TOPMOST); |
243 |
return; |
return E_FAIL; |
244 |
} |
} |
245 |
|
|
246 |
xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore"); |
xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore"); |
247 |
if (xvid_decore_func == NULL) { |
if (xvid_decore_func == NULL) { |
248 |
|
xvid_global_func = NULL; |
249 |
|
FreeLibrary(m_hdll); |
250 |
|
m_hdll = NULL; |
251 |
MessageBox(0, "xvid_decore() not found", "Error", MB_TOPMOST); |
MessageBox(0, "xvid_decore() not found", "Error", MB_TOPMOST); |
252 |
return; |
return E_FAIL; |
253 |
} |
} |
254 |
|
|
255 |
if (xvid_global_func(0, XVID_GBL_INIT, &init, NULL) < 0) |
if (xvid_global_func(0, XVID_GBL_INIT, &init, NULL) < 0) |
256 |
{ |
{ |
257 |
|
xvid_global_func = NULL; |
258 |
|
xvid_decore_func = NULL; |
259 |
|
FreeLibrary(m_hdll); |
260 |
|
m_hdll = NULL; |
261 |
MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST); |
MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST); |
262 |
return; |
return E_FAIL; |
263 |
} |
} |
264 |
|
|
265 |
memset(&m_create, 0, sizeof(m_create)); |
memset(&m_create, 0, sizeof(m_create)); |
269 |
memset(&m_frame, 0, sizeof(m_frame)); |
memset(&m_frame, 0, sizeof(m_frame)); |
270 |
m_frame.version = XVID_VERSION; |
m_frame.version = XVID_VERSION; |
271 |
|
|
|
LoadRegistryInfo(); |
|
|
|
|
272 |
USE_IYUV = false; |
USE_IYUV = false; |
273 |
USE_YV12 = false; |
USE_YV12 = false; |
274 |
USE_YUY2 = false; |
USE_YUY2 = false; |
325 |
ar_y = 20; |
ar_y = 20; |
326 |
break; |
break; |
327 |
} |
} |
328 |
|
|
329 |
|
return S_OK; |
330 |
} |
} |
331 |
|
|
332 |
void CXvidDecoder::CloseLib() |
void CXvidDecoder::CloseLib() |
333 |
{ |
{ |
334 |
DPRINTF("Destructor"); |
DPRINTF("CloseLib"); |
335 |
|
|
336 |
if (m_create.handle != NULL) { |
if ((m_create.handle != NULL) && (xvid_decore_func != NULL)) |
337 |
|
{ |
338 |
xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0); |
xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0); |
339 |
m_create.handle = NULL; |
m_create.handle = NULL; |
340 |
} |
} |
343 |
FreeLibrary(m_hdll); |
FreeLibrary(m_hdll); |
344 |
m_hdll = NULL; |
m_hdll = NULL; |
345 |
} |
} |
346 |
|
xvid_decore_func = NULL; |
347 |
|
xvid_global_func = NULL; |
348 |
} |
} |
349 |
|
|
350 |
/* destructor */ |
/* destructor */ |
351 |
|
|
352 |
CXvidDecoder::~CXvidDecoder() |
CXvidDecoder::~CXvidDecoder() |
353 |
{ |
{ |
354 |
|
DPRINTF("Destructor"); |
355 |
CloseLib(); |
CloseLib(); |
356 |
} |
} |
357 |
|
|
373 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
374 |
} |
} |
375 |
|
|
376 |
|
if (m_hdll == NULL) |
377 |
|
{ |
378 |
|
HRESULT hr = OpenLib(); |
379 |
|
|
380 |
|
if (FAILED(hr) || (m_hdll == NULL)) // Paranoid checks. |
381 |
|
return VFW_E_TYPE_NOT_ACCEPTED; |
382 |
|
} |
383 |
|
|
384 |
if (*mtIn->FormatType() == FORMAT_VideoInfo) |
if (*mtIn->FormatType() == FORMAT_VideoInfo) |
385 |
{ |
{ |
386 |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format(); |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format(); |
396 |
} |
} |
397 |
DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y); |
DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y); |
398 |
} |
} |
399 |
|
else if (*mtIn->FormatType() == FORMAT_MPEG2Video) { |
400 |
|
MPEG2VIDEOINFO * mpgvi = (MPEG2VIDEOINFO*)mtIn->Format(); |
401 |
|
VIDEOINFOHEADER2 * vih2 = &mpgvi->hdr; |
402 |
|
hdr = &vih2->bmiHeader; |
403 |
|
if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { |
404 |
|
ar_x = vih2->dwPictAspectRatioX; |
405 |
|
ar_y = vih2->dwPictAspectRatioY; |
406 |
|
} |
407 |
|
DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y); |
408 |
|
|
409 |
|
/* haali media splitter reports VOL information in the format header */ |
410 |
|
|
411 |
|
if (mpgvi->cbSequenceHeader>0) { |
412 |
|
|
413 |
|
xvid_dec_stats_t stats; |
414 |
|
memset(&stats, 0, sizeof(stats)); |
415 |
|
stats.version = XVID_VERSION; |
416 |
|
|
417 |
|
if (m_create.handle == NULL) { |
418 |
|
if (xvid_decore_func == NULL) |
419 |
|
return E_FAIL; |
420 |
|
if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0) { |
421 |
|
DPRINTF("*** XVID_DEC_CREATE error"); |
422 |
|
return E_FAIL; |
423 |
|
} |
424 |
|
} |
425 |
|
|
426 |
|
m_frame.general = 0; |
427 |
|
m_frame.bitstream = (void*)mpgvi->dwSequenceHeader; |
428 |
|
m_frame.length = mpgvi->cbSequenceHeader; |
429 |
|
m_frame.output.csp = XVID_CSP_NULL; |
430 |
|
|
431 |
|
int ret = 0; |
432 |
|
if ((ret=xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats)) >= 0) { |
433 |
|
/* honour video dimensions reported in VOL header */ |
434 |
|
if (stats.type == XVID_TYPE_VOL) { |
435 |
|
hdr->biWidth = stats.data.vol.width; |
436 |
|
hdr->biHeight = stats.data.vol.height; |
437 |
|
} |
438 |
|
} |
439 |
|
if (ret == XVID_ERR_MEMORY) return E_FAIL; |
440 |
|
} |
441 |
|
} |
442 |
else |
else |
443 |
{ |
{ |
444 |
DPRINTF("Error: Unknown FormatType"); |
DPRINTF("Error: Unknown FormatType"); |
456 |
|
|
457 |
switch(hdr->biCompression) |
switch(hdr->biCompression) |
458 |
{ |
{ |
459 |
|
case FOURCC_mp4v: |
460 |
case FOURCC_MP4V: |
case FOURCC_MP4V: |
461 |
if (!(g_config.supported_4cc & SUPPORT_MP4V)) { |
if (!(g_config.supported_4cc & SUPPORT_MP4V)) { |
462 |
CloseLib(); |
CloseLib(); |
488 |
CloseLib(); |
CloseLib(); |
489 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
490 |
} |
} |
491 |
|
|
492 |
|
m_create.fourcc = hdr->biCompression; |
493 |
|
|
494 |
return S_OK; |
return S_OK; |
495 |
} |
} |
496 |
|
|
632 |
|
|
633 |
|
|
634 |
/* (internal function) change colorspace */ |
/* (internal function) change colorspace */ |
635 |
|
#define CALC_BI_STRIDE(width,bitcount) ((((width * bitcount) + 31) & ~31) >> 3) |
636 |
|
|
637 |
HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format) |
HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format) |
638 |
{ |
{ |
639 |
|
DWORD biWidth; |
640 |
|
|
641 |
if (formattype == FORMAT_VideoInfo) |
if (formattype == FORMAT_VideoInfo) |
642 |
{ |
{ |
643 |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format; |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format; |
644 |
m_frame.output.stride[0] = (((vih->bmiHeader.biWidth * vih->bmiHeader.biBitCount) + 31) & ~31) >> 3; |
biWidth = vih->bmiHeader.biWidth; |
645 |
|
m_frame.output.stride[0] = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount); |
646 |
rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP); |
rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP); |
647 |
} |
} |
648 |
else if (formattype == FORMAT_VideoInfo2) |
else if (formattype == FORMAT_VideoInfo2) |
649 |
{ |
{ |
650 |
VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format; |
VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format; |
651 |
m_frame.output.stride[0] = (((vih2->bmiHeader.biWidth * vih2->bmiHeader.biBitCount) + 31) & ~31) >> 3; |
biWidth = vih2->bmiHeader.biWidth; |
652 |
|
m_frame.output.stride[0] = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount); |
653 |
rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP); |
rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP); |
654 |
} |
} |
655 |
else |
else |
662 |
DPRINTF("IYUV"); |
DPRINTF("IYUV"); |
663 |
rgb_flip = 0; |
rgb_flip = 0; |
664 |
m_frame.output.csp = XVID_CSP_I420; |
m_frame.output.csp = XVID_CSP_I420; |
665 |
m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3; /* planar format fix */ |
m_frame.output.stride[0] = CALC_BI_STRIDE(biWidth, 8); /* planar format fix */ |
666 |
} |
} |
667 |
else if (subtype == MEDIASUBTYPE_YV12) |
else if (subtype == MEDIASUBTYPE_YV12) |
668 |
{ |
{ |
669 |
DPRINTF("YV12"); |
DPRINTF("YV12"); |
670 |
rgb_flip = 0; |
rgb_flip = 0; |
671 |
m_frame.output.csp = XVID_CSP_YV12; |
m_frame.output.csp = XVID_CSP_YV12; |
672 |
m_frame.output.stride[0] = (m_frame.output.stride[0] * 2) / 3; /* planar format fix */ |
m_frame.output.stride[0] = CALC_BI_STRIDE(biWidth, 8); /* planar format fix */ |
673 |
} |
} |
674 |
else if (subtype == MEDIASUBTYPE_YUY2) |
else if (subtype == MEDIASUBTYPE_YUY2) |
675 |
{ |
{ |
793 |
|
|
794 |
if (m_create.handle == NULL) |
if (m_create.handle == NULL) |
795 |
{ |
{ |
796 |
|
if (xvid_decore_func == NULL) |
797 |
|
return E_FAIL; |
798 |
|
|
799 |
if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0) |
if (xvid_decore_func(0, XVID_DEC_CREATE, &m_create, 0) < 0) |
800 |
{ |
{ |
801 |
DPRINTF("*** XVID_DEC_CREATE error"); |
DPRINTF("*** XVID_DEC_CREATE error"); |
802 |
return S_FALSE; |
return E_FAIL; |
803 |
} |
} |
804 |
} |
} |
805 |
|
|
855 |
m_frame.output.csp &= ~XVID_CSP_VFLIP; |
m_frame.output.csp &= ~XVID_CSP_VFLIP; |
856 |
m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0); |
m_frame.output.csp |= rgb_flip^(g_config.nFlipVideo ? XVID_CSP_VFLIP : 0); |
857 |
|
|
858 |
|
// Paranoid check. |
859 |
|
if (xvid_decore_func == NULL) |
860 |
|
return E_FAIL; |
861 |
|
|
862 |
|
|
863 |
|
|
867 |
{ |
{ |
868 |
length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats); |
length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats); |
869 |
|
|
870 |
if (length < 0) |
if (length == XVID_ERR_MEMORY) |
871 |
|
return E_FAIL; |
872 |
|
else if (length < 0) |
873 |
{ |
{ |
874 |
DPRINTF("*** XVID_DEC_DECODE"); |
DPRINTF("*** XVID_DEC_DECODE"); |
875 |
return S_FALSE; |
return S_FALSE; |
876 |
} else |
} else |
877 |
if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) { |
if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) { |
|
// inspired by minolta! works for VMR 7 + 9 |
|
878 |
|
|
879 |
|
if (stats.type != XVID_TYPE_NOTHING) { /* dont attempt to set vmr aspect ratio if no frame was returned by decoder */ |
880 |
|
// inspired by minolta! works for VMR 7 + 9 |
881 |
IMediaSample2 *pOut2 = NULL; |
IMediaSample2 *pOut2 = NULL; |
882 |
AM_SAMPLE2_PROPERTIES outProp2; |
AM_SAMPLE2_PROPERTIES outProp2; |
883 |
if (SUCCEEDED(pOut->QueryInterface(IID_IMediaSample2, (void **)&pOut2)) && |
if (SUCCEEDED(pOut->QueryInterface(IID_IMediaSample2, (void **)&pOut2)) && |
898 |
} |
} |
899 |
} |
} |
900 |
} |
} |
901 |
|
} |
902 |
else |
else |
903 |
{ /* Preroll frame - won't be displayed */ |
{ /* Preroll frame - won't be displayed */ |
904 |
int tmp = m_frame.output.csp; |
int tmp = m_frame.output.csp; |
913 |
m_frame.general &= ~XVID_FILMEFFECT; |
m_frame.general &= ~XVID_FILMEFFECT; |
914 |
|
|
915 |
length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats); |
length = xvid_decore_func(m_create.handle, XVID_DEC_DECODE, &m_frame, &stats); |
916 |
if (length < 0) |
if (length == XVID_ERR_MEMORY) |
917 |
|
return E_FAIL; |
918 |
|
else if (length < 0) |
919 |
{ |
{ |
920 |
DPRINTF("*** XVID_DEC_DECODE"); |
DPRINTF("*** XVID_DEC_DECODE"); |
921 |
return S_FALSE; |
return S_FALSE; |
948 |
par_x = stats.data.vol.par_width; |
par_x = stats.data.vol.par_width; |
949 |
par_y = stats.data.vol.par_height; |
par_y = stats.data.vol.par_height; |
950 |
} else { |
} else { |
951 |
par_x = PARS[stats.data.vol.par][0]; |
par_x = PARS[stats.data.vol.par-1][0]; |
952 |
par_y = PARS[stats.data.vol.par][1]; |
par_y = PARS[stats.data.vol.par-1][1]; |
953 |
} |
} |
954 |
|
|
955 |
ar_x = par_x * stats.data.vol.width; |
ar_x = par_x * stats.data.vol.width; |