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.7 2004-04-18 07:55:11 syskin Exp $ |
* $Id: CXvidDecoder.cpp,v 1.13 2004-10-25 10:29:10 suxen_drol Exp $ |
23 |
* |
* |
24 |
****************************************************************************/ |
****************************************************************************/ |
25 |
|
|
36 |
place these paths at the top of the Tools|Options|Directories list |
place these paths at the top of the Tools|Options|Directories list |
37 |
|
|
38 |
headers: |
headers: |
39 |
C:\DXVCSDK\include |
C:\DX90SDK\Include |
40 |
C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses |
C:\DX90SDK\Samples\C++\DirectShow\BaseClasses |
41 |
|
|
42 |
libraries (optional): |
C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Release |
43 |
C:\DXVCSDK\samples\Multimedia\DirectShow\BaseClasses\Release |
C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\Debug |
44 |
*/ |
*/ |
45 |
|
|
46 |
|
|
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 |
void CXvidDecoder::CloseLib() |
void CXvidDecoder::CloseLib() |
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"); |
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 |
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)); |
549 |
|
|
550 |
|
|
551 |
/* (internal function) change colorspace */ |
/* (internal function) change colorspace */ |
552 |
|
#define CALC_BI_STRIDE(width,bitcount) ((((width * bitcount) + 31) & ~31) >> 3) |
553 |
|
|
554 |
HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format) |
HRESULT CXvidDecoder::ChangeColorspace(GUID subtype, GUID formattype, void * format) |
555 |
{ |
{ |
556 |
|
DWORD biWidth; |
557 |
|
|
558 |
if (formattype == FORMAT_VideoInfo) |
if (formattype == FORMAT_VideoInfo) |
559 |
{ |
{ |
560 |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format; |
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER * )format; |
561 |
m_frame.output.stride[0] = (((vih->bmiHeader.biWidth * vih->bmiHeader.biBitCount) + 31) & ~31) >> 3; |
biWidth = vih->bmiHeader.biWidth; |
562 |
|
m_frame.output.stride[0] = CALC_BI_STRIDE(vih->bmiHeader.biWidth, vih->bmiHeader.biBitCount); |
563 |
rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP); |
rgb_flip = (vih->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP); |
564 |
} |
} |
565 |
else if (formattype == FORMAT_VideoInfo2) |
else if (formattype == FORMAT_VideoInfo2) |
566 |
{ |
{ |
567 |
VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format; |
VIDEOINFOHEADER2 * vih2 = (VIDEOINFOHEADER2 * )format; |
568 |
m_frame.output.stride[0] = (((vih2->bmiHeader.biWidth * vih2->bmiHeader.biBitCount) + 31) & ~31) >> 3; |
biWidth = vih2->bmiHeader.biWidth; |
569 |
|
m_frame.output.stride[0] = CALC_BI_STRIDE(vih2->bmiHeader.biWidth, vih2->bmiHeader.biBitCount); |
570 |
rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP); |
rgb_flip = (vih2->bmiHeader.biHeight < 0 ? 0 : XVID_CSP_VFLIP); |
571 |
} |
} |
572 |
else |
else |
579 |
DPRINTF("IYUV"); |
DPRINTF("IYUV"); |
580 |
rgb_flip = 0; |
rgb_flip = 0; |
581 |
m_frame.output.csp = XVID_CSP_I420; |
m_frame.output.csp = XVID_CSP_I420; |
582 |
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 */ |
583 |
} |
} |
584 |
else if (subtype == MEDIASUBTYPE_YV12) |
else if (subtype == MEDIASUBTYPE_YV12) |
585 |
{ |
{ |
586 |
DPRINTF("YV12"); |
DPRINTF("YV12"); |
587 |
rgb_flip = 0; |
rgb_flip = 0; |
588 |
m_frame.output.csp = XVID_CSP_YV12; |
m_frame.output.csp = XVID_CSP_YV12; |
589 |
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 */ |
590 |
} |
} |
591 |
else if (subtype == MEDIASUBTYPE_YUY2) |
else if (subtype == MEDIASUBTYPE_YUY2) |
592 |
{ |
{ |
769 |
m_frame.output.csp &= ~XVID_CSP_VFLIP; |
m_frame.output.csp &= ~XVID_CSP_VFLIP; |
770 |
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); |
771 |
|
|
772 |
|
|
773 |
|
|
774 |
|
|
775 |
repeat : |
repeat : |
776 |
|
|
777 |
if (pIn->IsPreroll() != S_OK) |
if (pIn->IsPreroll() != S_OK) |
782 |
{ |
{ |
783 |
DPRINTF("*** XVID_DEC_DECODE"); |
DPRINTF("*** XVID_DEC_DECODE"); |
784 |
return S_FALSE; |
return S_FALSE; |
785 |
|
} else |
786 |
|
if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1 && forced_ar == false) { |
787 |
|
// inspired by minolta! works for VMR 7 + 9 |
788 |
|
|
789 |
|
IMediaSample2 *pOut2 = NULL; |
790 |
|
AM_SAMPLE2_PROPERTIES outProp2; |
791 |
|
if (SUCCEEDED(pOut->QueryInterface(IID_IMediaSample2, (void **)&pOut2)) && |
792 |
|
SUCCEEDED(pOut2->GetProperties(FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&outProp2))) |
793 |
|
{ |
794 |
|
CMediaType mtOut2 = m_pOutput->CurrentMediaType(); |
795 |
|
VIDEOINFOHEADER2* vihOut2 = (VIDEOINFOHEADER2*)mtOut2.Format(); |
796 |
|
|
797 |
|
if (*mtOut2.FormatType() == FORMAT_VideoInfo2 && |
798 |
|
vihOut2->dwPictAspectRatioX != ar_x && vihOut2->dwPictAspectRatioY != ar_y) |
799 |
|
{ |
800 |
|
vihOut2->dwPictAspectRatioX = ar_x; |
801 |
|
vihOut2->dwPictAspectRatioY = ar_y; |
802 |
|
pOut2->SetMediaType(&mtOut2); |
803 |
|
m_pOutput->SetMediaType(&mtOut2); |
804 |
|
} |
805 |
|
pOut2->Release(); |
806 |
|
} |
807 |
} |
} |
808 |
} |
} |
809 |
else |
else |
845 |
return S_FALSE; |
return S_FALSE; |
846 |
} |
} |
847 |
|
|
|
// pOut->SetDiscontinuity(TRUE); |
|
848 |
pOut->SetSyncPoint(TRUE); |
pOut->SetSyncPoint(TRUE); |
849 |
|
|
850 |
|
if (g_config.aspect_ratio == 0 || g_config.aspect_ratio == 1) { /* auto */ |
851 |
|
int par_x, par_y; |
852 |
|
if (stats.data.vol.par == XVID_PAR_EXT) { |
853 |
|
par_x = stats.data.vol.par_width; |
854 |
|
par_y = stats.data.vol.par_height; |
855 |
|
} else { |
856 |
|
par_x = PARS[stats.data.vol.par-1][0]; |
857 |
|
par_y = PARS[stats.data.vol.par-1][1]; |
858 |
|
} |
859 |
|
|
860 |
|
ar_x = par_x * stats.data.vol.width; |
861 |
|
ar_y = par_y * stats.data.vol.height; |
862 |
|
} |
863 |
|
|
864 |
m_frame.bitstream = (BYTE*)m_frame.bitstream + length; |
m_frame.bitstream = (BYTE*)m_frame.bitstream + length; |
865 |
m_frame.length -= length; |
m_frame.length -= length; |
866 |
goto repeat; |
goto repeat; |