Здравствуйте, andrey.viktorov, Вы писали:
AV>Возникла идея: поставить у ISampleGrabber'а, который хватает битмапы, в AM_MEDIA_TYPE нужный формат битмапа и попробовать установить соединение между пинами в таком формате. Такое возможно? В общем, было бы просто супер, если можно это сделать средствами DirectShow. А нужно сделать следующее : есть семпл определённой длины и ширины, его необходимо подогонать в окно 320х240 не изменяя пропорций (если один из размеров получаются меньше, то оставшееся пространство забивается чёрными пикселями и получаются аля полосы как широкоформатном видео).
Не все так просто как кажеться. Да, конечно возможно, либо используй PushSource Filter для поставки видеокадров. Если хочешь в реальном времени про GDI забудь. Сейчас занимаюсь аналогичной задачей, не знаю получиться ли в реальном времени, но чувствую что — нет, вот откуда такие мысли. Сейчас я написал программу для генерации видеопотока но основе определенных спрайтов которые генерируються на отдельной машине. Потому что когда я попробовал рисовать прямо в буфер кадра, естественно производительность заставляла желать лучшего. После того как я начал генерировать спрайты на отдельной машине, попробовал опять посредством GDI составлять картинку из спрайтов, но опять таки получались довольно приличные тормоза, но уже меньше

) Решил делать посредством memcpy(pSample, pBackBuf, _screenSize), просто у меня задачка еще свзана с тем что аппаратное обеспечение очень специализированное и аппаратное ускорение графики как таковое отсутствует.
Я делаю:
hr = m_pIPushSource->GetFrameBuffer(&pSample);
if (SUCCEEDED(hr))
{
hr = pSample->GetPointer(&pBuffer);
cbBuffer = pSample->GetActualDataLength();
if (pamt && pvih)
WriteBuffer(pBuffer); // тут внутри memcpy про который я говорил выше
if (SUCCEEDED(m_pIPushSource->Deliver(pSample)))
{
m_FrameCount += 1;
pBuffer = NULL;
}
...
}
Далее, функция DrawBackBuffer примерно следующего содержания, вызываеться в WriteBuffer перед memcpy(...):
byte* DrawBackBuffer(byte* pScreen)
{
...
int _size = dwWidth*dwHeight*4 + (dwWidth*4*400); // специфика такая, бэкбуфер должен быть больше рабочего кадра, не имеет отношения к теме ;)
if(backbuf == NULL)
backbuf = new byte[_size];
// дальше "рисуем"
for(int i=0; i < m_vImages.size(); i++)
{
...
m_vImages[i]->LockBits(&rect, ImageLockModeRead,
PixelFormat32bppRGB, &bitmapData);
pixels = (unsigned char*)bitmapData.Scan0;
DrawImage(x, calc_y, backbuf, pixels)
}
...
return backbuf+dwWidth*4*200;
}
Ну и DrawImage:
void DrawImage(..., u_char* src, u_char* dst)
{
...
for(UINT i=0; i < s_height; i++)
{
UINT line = dwHeight - dst_y;
UINT line_mem = (i+line)*(dst_width*4);
memcpy((void*)&dst[line_mem + x_offs],
(void*)&src[(s_height - 1 - i)*s_len], s_len);
}
}
Все работет отлично. Теперь у меня появилась потребность ко всей этой каше еще подмешать видеопоток с масштабированием, какзлось бы все просто, действуем по аналогии, ан нет, после небольшого теста пришел к сомнению что получиться, а тест был следующий, я добавил функцию, TestMask(... u_char* buf) примерно следующего содержания:
TestMask(... u_char* buf)
{
for(int i=0; i < dwHeight; i++)
{
for(int y=1; y < dwWidth; y++)
{
buf[i*(y+2)] = buf[i*(y+2)] && 0x0a;
}
}
}
И у меня стало видно подтормаживание видеопотока. Масштабирование планирую делать как нибудь так
http://www.enlight.ru/demo/faq/smth.phtml?query=alg_scale_bitmap. Если интересно, сообщу о результатах позже, через пару-тройку дней.