Hi Experts,
Link to my Full source code:
https://docs.google.com/file/d/0B9qC3OVDGTjuM2xaeGx1Q0NUYWs/edit[
^]
(in the Debug folder there is Resizer.dll, and need to register it first then in graph edit select any video file(using file source filer), then add "RGB Resizer" and use it to resize the video)
I am creating a new resizer Filter, I added a property page where user can select different outputs (pal(720X576), ntsc(720X480)...)
By default pal is selected and if i played it working fine.
after playing with pal and if i changed the output to ntsc video is not displaying correctly(problem is top part of the header is getting croped.)
If i disconnect the output and input pins of my filter and then change the output settings and after reconnecting it seems to be working fine.
How to fix this issue?(with out disconnecting the pins i need to change the output settings)
below is my code(the code i am using is from a sample i found online, i added the property page)
I guess i need to change ScaleBuf() but i dont have any clues how to fix this.
HRESULT CResizer::CheckInputType(const CMediaType *mtIn)
{
GUID subtypeIn = *mtIn->Subtype();
if( *mtIn->FormatType() == FORMAT_VideoInfo &&
(subtypeIn == MEDIASUBTYPE_RGB555 || subtypeIn == MEDIASUBTYPE_RGB565 ||
subtypeIn == MEDIASUBTYPE_RGB24 || subtypeIn == MEDIASUBTYPE_RGB32))
{
BITMAPINFOHEADER *pbih = &((VIDEOINFOHEADER*)mtIn->Format())->bmiHeader;
m_inX = pbih->biWidth;
m_inY = pbih->biHeight;
m_bMakeTables = true;
return S_OK;
}
return VFW_E_INVALID_MEDIA_TYPE;
}
HRESULT CResizer::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
{
GUID subtypeIn = *mtIn->Subtype();
GUID subtypeOut = *mtOut->Subtype();
if(subtypeIn == subtypeOut && (subtypeIn == MEDIASUBTYPE_RGB555 || subtypeIn == MEDIASUBTYPE_RGB565 ||
subtypeIn == MEDIASUBTYPE_RGB24 || subtypeIn == MEDIASUBTYPE_RGB32) )
return S_OK;
return VFW_E_INVALID_MEDIA_TYPE;
}
HRESULT CResizer::DecideBufferSize(IMemAllocator *pAlloc,ALLOCATOR_PROPERTIES *pProperties)
{
if (!m_pInput->IsConnected())
return E_UNEXPECTED;
ALLOCATOR_PROPERTIES InputProps;
IMemAllocator *pAllocInput = 0;
HRESULT hr = m_pInput->GetAllocator(&pAllocInput);
if (FAILED(hr))
{
return hr;
}
hr = pAllocInput->GetProperties(&InputProps);
pAllocInput->Release();
if (FAILED(hr))
{
return hr;
}
if (pProperties->cbAlign == 0)
{
pProperties->cbAlign = 1;
}
if (pProperties->cbBuffer == 0)
{
pProperties->cBuffers = 1;
}
pProperties->cbBuffer = max(InputProps.cbBuffer, pProperties->cbBuffer);
ALLOCATOR_PROPERTIES Actual;
hr = pAlloc->SetProperties(pProperties, &Actual);
if (FAILED(hr))
{
return hr;
}
if (InputProps.cbBuffer > Actual.cbBuffer)
{
return E_FAIL;
}
return S_OK;
}
HRESULT CResizer::GetMediaType(int iPosition, CMediaType *pMediaType)
{
if (!m_pInput->IsConnected())
return E_UNEXPECTED;
if (iPosition < 0)
return E_INVALIDARG;
if (iPosition > 0)
return VFW_S_NO_MORE_ITEMS;
CMediaType *inMediaType = &m_pInput->CurrentMediaType();
VIDEOINFOHEADER *vihIn = (VIDEOINFOHEADER*)inMediaType->Format();
m_bytesPerPixel = vihIn->bmiHeader.biBitCount / 8;
pMediaType->SetFormatType(&FORMAT_VideoInfo);
pMediaType->SetType(&MEDIATYPE_Video);
pMediaType->SetSubtype(inMediaType->Subtype());
pMediaType->SetSampleSize(RowWidth(m_outX) * m_outY * m_bytesPerPixel);
pMediaType->SetTemporalCompression(FALSE);
VIDEOINFOHEADER *vihOut = (VIDEOINFOHEADER *)pMediaType->ReallocFormatBuffer(sizeof(VIDEOINFOHEADER));
memset(vihOut, 0, sizeof(VIDEOINFOHEADER));
double frameRate = vihIn->AvgTimePerFrame / 10000000.0;
vihOut->dwBitRate = (int)(frameRate * m_outY * m_outX * m_bytesPerPixel);
vihOut->AvgTimePerFrame = vihIn->AvgTimePerFrame;
vihOut->bmiHeader.biBitCount = m_bytesPerPixel * 8;
vihOut->bmiHeader.biCompression = BI_RGB;
vihOut->bmiHeader.biHeight = m_outY;
vihOut->bmiHeader.biWidth = m_outX;
vihOut->bmiHeader.biPlanes = 1;
vihOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
vihOut->bmiHeader.biSizeImage = RowWidth(m_outX) * m_outY * m_bytesPerPixel;
return NOERROR;
}
void CResizer::MakeScaleTables()
{
double xStep = (double)m_inX / m_outX;
double yStep = (double)m_inY / m_outY;
int inRowBytes = RowWidth(m_inX * m_bytesPerPixel);
int inY, inX;
for(int y = 0; y < m_outY; ++y)
{
inY = y * yStep;
m_iSrcScanLine[y] = (inY * inRowBytes);
}
for(int x = 0; x < m_outX; ++x)
{
inX = x * xStep;
m_iSrcPixelOffset[x] = (inX * m_bytesPerPixel);
}
}
void CResizer::ScaleBuf(BYTE *in, BYTE *out)
{
UCHAR *dstPixel = out;
UCHAR *srcScanLine, *srcPixel;
for(int y = 0; y < m_outY; ++y)
{
srcScanLine = in + m_iSrcScanLine[y];
switch(m_bytesPerPixel)
{
case 4:
for(int x = 0; x < m_outX; ++x)
{
srcPixel = srcScanLine + m_iSrcPixelOffset[x];
*dstPixel++ = *srcPixel++;
*dstPixel++ = *srcPixel++;
*dstPixel++ = *srcPixel++;
*dstPixel++ = *srcPixel++;
}
break;
case 3:
for(int x = 0; x < m_outX; ++x)
{
srcPixel = srcScanLine + m_iSrcPixelOffset[x];
*dstPixel++ = *srcPixel++;
*dstPixel++ = *srcPixel++;
*dstPixel++ = *srcPixel++;
}
break;
case 2:
for(int x = 0; x < m_outX; ++x)
{
srcPixel = srcScanLine + m_iSrcPixelOffset[x];
*dstPixel++ = *srcPixel++;
*dstPixel++ = *srcPixel++;
}
break;
case 1:
for(int x = 0; x < m_outX; ++x)
{
srcPixel = srcScanLine + m_iSrcPixelOffset[x];
*dstPixel++ = *srcPixel++;
}
break;
}
}
}