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.2 2004-03-22 23:35:11 edgomez Exp $ |
* $Id: CXvidDecoder.cpp,v 1.10 2004-07-18 00:58:14 suxen_drol Exp $ |
23 |
* |
* |
24 |
****************************************************************************/ |
****************************************************************************/ |
25 |
|
|
212 |
memset(&init, 0, sizeof(init)); |
memset(&init, 0, sizeof(init)); |
213 |
init.version = XVID_VERSION; |
init.version = XVID_VERSION; |
214 |
|
|
|
ar_x = ar_y = 0; |
|
|
|
|
215 |
m_hdll = LoadLibrary(XVID_DLL_NAME); |
m_hdll = LoadLibrary(XVID_DLL_NAME); |
216 |
if (m_hdll == NULL) { |
if (m_hdll == NULL) { |
217 |
DPRINTF("dll load failed"); |
DPRINTF("dll load failed"); |
218 |
MessageBox(0, XVID_DLL_NAME " not found","Error", 0); |
MessageBox(0, XVID_DLL_NAME " not found","Error", MB_TOPMOST); |
219 |
return; |
return; |
220 |
} |
} |
221 |
|
|
222 |
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"); |
223 |
if (xvid_global_func == NULL) { |
if (xvid_global_func == NULL) { |
224 |
MessageBox(0, "xvid_global() not found", "Error", 0); |
MessageBox(0, "xvid_global() not found", "Error", MB_TOPMOST); |
225 |
return; |
return; |
226 |
} |
} |
227 |
|
|
228 |
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"); |
229 |
if (xvid_decore_func == NULL) { |
if (xvid_decore_func == NULL) { |
230 |
MessageBox(0, "xvid_decore() not found", "Error", 0); |
MessageBox(0, "xvid_decore() not found", "Error", MB_TOPMOST); |
231 |
return; |
return; |
232 |
} |
} |
233 |
|
|
234 |
if (xvid_global_func(0, XVID_GBL_INIT, &init, NULL) < 0) |
if (xvid_global_func(0, XVID_GBL_INIT, &init, NULL) < 0) |
235 |
{ |
{ |
236 |
MessageBox(0, "xvid_global() failed", "Error", 0); |
MessageBox(0, "xvid_global() failed", "Error", MB_TOPMOST); |
237 |
return; |
return; |
238 |
} |
} |
239 |
|
|
283 |
USE_RGB32 = true; |
USE_RGB32 = true; |
284 |
break; |
break; |
285 |
} |
} |
|
} |
|
|
|
|
286 |
|
|
287 |
|
switch (g_config.aspect_ratio) |
288 |
|
{ |
289 |
|
case 0: |
290 |
|
case 1: |
291 |
|
break; |
292 |
|
case 2: |
293 |
|
ar_x = 4; |
294 |
|
ar_y = 3; |
295 |
|
break; |
296 |
|
case 3: |
297 |
|
ar_x = 16; |
298 |
|
ar_y = 9; |
299 |
|
break; |
300 |
|
case 4: |
301 |
|
ar_x = 47; |
302 |
|
ar_y = 20; |
303 |
|
break; |
304 |
|
} |
305 |
|
} |
306 |
|
|
307 |
/* destructor */ |
void CXvidDecoder::CloseLib() |
|
|
|
|
CXvidDecoder::~CXvidDecoder() |
|
308 |
{ |
{ |
309 |
DPRINTF("Destructor"); |
DPRINTF("Destructor"); |
310 |
|
|
311 |
if (m_create.handle != NULL) |
if (m_create.handle != NULL) { |
|
{ |
|
312 |
xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0); |
xvid_decore_func(m_create.handle, XVID_DEC_DESTROY, 0, 0); |
313 |
m_create.handle = NULL; |
m_create.handle = NULL; |
314 |
} |
} |
315 |
|
|
316 |
if (m_hdll != NULL) |
if (m_hdll != NULL) { |
|
{ |
|
317 |
FreeLibrary(m_hdll); |
FreeLibrary(m_hdll); |
318 |
m_hdll = NULL; |
m_hdll = NULL; |
319 |
} |
} |
320 |
} |
} |
321 |
|
|
322 |
|
/* destructor */ |
323 |
|
|
324 |
|
CXvidDecoder::~CXvidDecoder() |
325 |
|
{ |
326 |
|
CloseLib(); |
327 |
|
} |
328 |
|
|
329 |
|
|
330 |
|
|
331 |
/* check input type */ |
/* check input type */ |
335 |
DPRINTF("CheckInputType"); |
DPRINTF("CheckInputType"); |
336 |
BITMAPINFOHEADER * hdr; |
BITMAPINFOHEADER * hdr; |
337 |
|
|
338 |
|
ar_x = ar_y = 0; |
339 |
|
|
340 |
if (*mtIn->Type() != MEDIATYPE_Video) |
if (*mtIn->Type() != MEDIATYPE_Video) |
341 |
{ |
{ |
342 |
DPRINTF("Error: Unknown Type"); |
DPRINTF("Error: Unknown Type"); |
343 |
|
CloseLib(); |
344 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
345 |
} |
} |
346 |
|
|
348 |
{ |
{ |
349 |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format(); |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtIn->Format(); |
350 |
hdr = &vih->bmiHeader; |
hdr = &vih->bmiHeader; |
|
/* PAR (x:y) is (1/ppm_X):(1/ppm_Y) where ppm is pixels-per-meter |
|
|
which is equal to ppm_Y:ppm_X */ |
|
|
ar_x = vih->bmiHeader.biYPelsPerMeter * abs(hdr->biWidth); |
|
|
ar_y = vih->bmiHeader.biXPelsPerMeter * abs(hdr->biHeight); |
|
|
DPRINTF("VIDEOINFOHEADER PAR: %d:%d -> AR %d:%d", |
|
|
vih->bmiHeader.biYPelsPerMeter,vih->bmiHeader.biXPelsPerMeter, ar_x, ar_y); |
|
351 |
} |
} |
352 |
else if (*mtIn->FormatType() == FORMAT_VideoInfo2) |
else if (*mtIn->FormatType() == FORMAT_VideoInfo2) |
353 |
{ |
{ |
354 |
VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format(); |
VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 *) mtIn->Format(); |
355 |
hdr = &vih2->bmiHeader; |
hdr = &vih2->bmiHeader; |
356 |
|
if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { |
357 |
ar_x = vih2->dwPictAspectRatioX; |
ar_x = vih2->dwPictAspectRatioX; |
358 |
ar_y = vih2->dwPictAspectRatioY; |
ar_y = vih2->dwPictAspectRatioY; |
359 |
|
} |
360 |
DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y); |
DPRINTF("VIDEOINFOHEADER2 AR: %d:%d", ar_x, ar_y); |
361 |
} |
} |
362 |
else |
else |
363 |
{ |
{ |
364 |
DPRINTF("Error: Unknown FormatType"); |
DPRINTF("Error: Unknown FormatType"); |
365 |
|
CloseLib(); |
366 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
367 |
} |
} |
368 |
|
|
378 |
{ |
{ |
379 |
|
|
380 |
case FOURCC_MP4V: |
case FOURCC_MP4V: |
381 |
if (!(g_config.supported_4cc & SUPPORT_MP4V)) return VFW_E_TYPE_NOT_ACCEPTED; |
if (!(g_config.supported_4cc & SUPPORT_MP4V)) { |
382 |
|
CloseLib(); |
383 |
|
return VFW_E_TYPE_NOT_ACCEPTED; |
384 |
|
} |
385 |
break; |
break; |
386 |
case FOURCC_DIVX : |
case FOURCC_DIVX : |
387 |
if (!(g_config.supported_4cc & SUPPORT_DIVX)) return VFW_E_TYPE_NOT_ACCEPTED; |
if (!(g_config.supported_4cc & SUPPORT_DIVX)) { |
388 |
|
CloseLib(); |
389 |
|
return VFW_E_TYPE_NOT_ACCEPTED; |
390 |
|
} |
391 |
break; |
break; |
392 |
case FOURCC_DX50 : |
case FOURCC_DX50 : |
393 |
if (!(g_config.supported_4cc & SUPPORT_DX50)) return VFW_E_TYPE_NOT_ACCEPTED; |
if (!(g_config.supported_4cc & SUPPORT_DX50)) { |
394 |
|
CloseLib(); |
395 |
|
return VFW_E_TYPE_NOT_ACCEPTED; |
396 |
|
} |
397 |
case FOURCC_XVID : |
case FOURCC_XVID : |
398 |
break; |
break; |
399 |
|
|
405 |
(hdr->biCompression>>8)&0xff, |
(hdr->biCompression>>8)&0xff, |
406 |
(hdr->biCompression>>16)&0xff, |
(hdr->biCompression>>16)&0xff, |
407 |
(hdr->biCompression>>24)&0xff); |
(hdr->biCompression>>24)&0xff); |
408 |
|
CloseLib(); |
409 |
return VFW_E_TYPE_NOT_ACCEPTED; |
return VFW_E_TYPE_NOT_ACCEPTED; |
410 |
} |
} |
411 |
return S_OK; |
return S_OK; |
436 |
if (ar_x != 0 && ar_y != 0) { |
if (ar_x != 0 && ar_y != 0) { |
437 |
vih->dwPictAspectRatioX = ar_x; |
vih->dwPictAspectRatioX = ar_x; |
438 |
vih->dwPictAspectRatioY = ar_y; |
vih->dwPictAspectRatioY = ar_y; |
439 |
|
forced_ar = true; |
440 |
} else { // just to be safe |
} else { // just to be safe |
441 |
vih->dwPictAspectRatioX = m_create.width; |
vih->dwPictAspectRatioX = m_create.width; |
442 |
vih->dwPictAspectRatioY = abs(m_create.height); |
vih->dwPictAspectRatioY = abs(m_create.height); |
443 |
|
forced_ar = false; |
444 |
} |
} |
|
|
|
445 |
} else { |
} else { |
446 |
|
|
447 |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER)); |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mtOut->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER)); |
742 |
m_frame.general = XVID_LOWDELAY; |
m_frame.general = XVID_LOWDELAY; |
743 |
|
|
744 |
if (pIn->IsDiscontinuity() == S_OK) |
if (pIn->IsDiscontinuity() == S_OK) |
745 |
m_frame.general = XVID_DISCONTINUITY; |
m_frame.general |= XVID_DISCONTINUITY; |
746 |
|
|
747 |
if (g_config.nDeblock_Y) |
if (g_config.nDeblock_Y) |
748 |
m_frame.general |= XVID_DEBLOCKY; |
m_frame.general |= XVID_DEBLOCKY; |
749 |
|
|
750 |
if (g_config.nDeblock_UV) |
if (g_config.nDeblock_UV) |
751 |
m_frame.general |= XVID_DEBLOCKUV; |
m_frame.general |= XVID_DEBLOCKUV; |
752 |
/* |
|
753 |
if (g_config.nDering) |
if (g_config.nDering_Y) |
754 |
m_frame.general |= XVID_DERING; |
m_frame.general |= XVID_DERINGY; |
755 |
*/ |
|
756 |
|
if (g_config.nDering_UV) |
757 |
|
m_frame.general |= XVID_DERINGUV; |
758 |
|
|
759 |
if (g_config.nFilmEffect) |
if (g_config.nFilmEffect) |
760 |
m_frame.general |= XVID_FILMEFFECT; |
m_frame.general |= XVID_FILMEFFECT; |
761 |
|
|
762 |
|
m_frame.brightness = g_config.nBrightness; |
763 |
|
|
764 |
m_frame.output.csp &= ~XVID_CSP_VFLIP; |
m_frame.output.csp &= ~XVID_CSP_VFLIP; |
765 |
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); |
766 |
|
|
767 |
|
|
768 |
|
|
769 |
|
|
770 |
repeat : |
repeat : |
771 |
|
|
772 |
if (pIn->IsPreroll() != S_OK) |
if (pIn->IsPreroll() != S_OK) |
777 |
{ |
{ |
778 |
DPRINTF("*** XVID_DEC_DECODE"); |
DPRINTF("*** XVID_DEC_DECODE"); |
779 |
return S_FALSE; |
return S_FALSE; |
780 |
|
} else |
781 |
|
if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) { |
782 |
|
// inspired by minolta! works for VMR 7 + 9 |
783 |
|
|
784 |
|
IMediaSample2 *pOut2 = NULL; |
785 |
|
AM_SAMPLE2_PROPERTIES outProp2; |
786 |
|
if (SUCCEEDED(pOut->QueryInterface(IID_IMediaSample2, (void **)&pOut2)) && |
787 |
|
SUCCEEDED(pOut2->GetProperties(FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&outProp2))) |
788 |
|
{ |
789 |
|
CMediaType mtOut2 = m_pOutput->CurrentMediaType(); |
790 |
|
VIDEOINFOHEADER2* vihOut2 = (VIDEOINFOHEADER2*)mtOut2.Format(); |
791 |
|
|
792 |
|
if (*mtOut2.FormatType() == FORMAT_VideoInfo2 && |
793 |
|
vihOut2->dwPictAspectRatioX != ar_x && vihOut2->dwPictAspectRatioY != ar_y) |
794 |
|
{ |
795 |
|
vihOut2->dwPictAspectRatioX = ar_x; |
796 |
|
vihOut2->dwPictAspectRatioY = ar_y; |
797 |
|
pOut2->SetMediaType(&mtOut2); |
798 |
|
m_pOutput->SetMediaType(&mtOut2); |
799 |
|
} |
800 |
|
pOut2->Release(); |
801 |
|
} |
802 |
} |
} |
803 |
} |
} |
804 |
else |
else |
840 |
return S_FALSE; |
return S_FALSE; |
841 |
} |
} |
842 |
|
|
|
// pOut->SetDiscontinuity(TRUE); |
|
843 |
pOut->SetSyncPoint(TRUE); |
pOut->SetSyncPoint(TRUE); |
844 |
|
|
845 |
|
if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { /* auto */ |
846 |
|
int par_x, par_y; |
847 |
|
if (stats.data.vol.par == XVID_PAR_EXT) { |
848 |
|
par_x = stats.data.vol.par_width; |
849 |
|
par_y = stats.data.vol.par_height; |
850 |
|
} else { |
851 |
|
par_x = PARS[stats.data.vol.par][0]; |
852 |
|
par_y = PARS[stats.data.vol.par][1]; |
853 |
|
} |
854 |
|
|
855 |
|
ar_x = par_x * stats.data.vol.width; |
856 |
|
ar_y = par_y * stats.data.vol.height; |
857 |
|
} |
858 |
|
|
859 |
m_frame.bitstream = (BYTE*)m_frame.bitstream + length; |
m_frame.bitstream = (BYTE*)m_frame.bitstream + length; |
860 |
m_frame.length -= length; |
m_frame.length -= length; |
861 |
goto repeat; |
goto repeat; |