Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to handle dynamic format change from vmr9 when a source filter connect to it directly?

69 views
Skip to first unread message

ims...@gmail.com

unread,
Mar 24, 2013, 1:30:48 AM3/24/13
to
I am writing a source filter that output yv12 data(704x576 in pixel) to vmr9 directly,
the connection is good when the graph run, but the display is so horrible.

I am wondering how to fill media sample data in SourceStream::FillBuffer(), do I need to scale the yv12 data to the dimension as vmr9 required(1024x576), or I just need to padding it, and if padding is needed, how to do it?

The memory layout of yv12 data that source filter got is like this:
low memory address ........... high memory address
yyyy-yyyy-vv-uu

Does someone knows how to handle this dynamic format change?
I have read this topic:
http://us.generation-nt.com/answer/vmr-9-changes-resolution-during-start-streaming-help-27523272.html
But the author did not point out how did he resolve it.


The media type proposed to vmr9 when it call SourceStream::GetMediaType() is as below:
pmt->SetType(&MEDIATYPE_Video);
pmt->SetSubtype(&MEDIASUBTYPE_YV12);
pmt->SetFormatType(&FORMAT_VideoInfo);
pmt->SetTemporalCompression(FALSE);

VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
memset(vih, 0, sizeof(VIDEOINFOHEADER));
vih->AvgTimePerFrame = m_AvgTimePerFrame;
vih->bmiHeader.biSize = sizeof(vih->bmiHeader);
vih->bmiHeader.biWidth = 704;
vih->bmiHeader.biHeight = 576;
vih->bmiHeader.biPlanes = 1;
vih->bmiHeader.biBitCount = 12;
vih->bmiHeader.biCompression = '21VY';
vih->bmiHeader.biCompression = MAKEFOURCC('Y', 'V', '1', '2');
vih->bmiHeader.biSizeImage = vih->bmiHeader.biWidth * abs(vih->bmiHeader.biHeight) * vih->bmiHeader.biBitCount >> 3;

pmt->SetSampleSize(vih->bmiHeader.biSizeImage);

The vmr9 proposed its media type when call QueryAccept() on my output pin:
[format change]
WxH = 1024x576
rcSource = {0,0,704,576}
rcTarget = {0,0,704,540}

And the source filter just accept this format change by call SourceStream::CheckMediaType():
if (pmt->majortype == MEDIATYPE_Video
&& pmt->subtype == MEDIASUBTYPE_YV12
&& pmt->formattype == FORMAT_VideoInfo) {
return S_OK;
}


ims...@gmail.com

unread,
Mar 24, 2013, 3:38:27 AM3/24/13
to
I found the solution, it is simple...

The vmr9 proposed its media type when call QueryAccept() on my output pin:
[format change]
WxH = 1024x576
rcSource = {0,0,704,576}
rcTarget = {0,0,704,576}

Then in FillBuffer(), what need to do is:
// fill Y rect
for (int y = 0, p = min(704, 1024);
y < 576;
y++, pIn += 704, pOut += 1024) {
memcpy(pOut, pIn, p);
}
// fill V rect
for (int y = 0, p = min(704/2, 1024/2);
y < 576/2;
y++, pIn += 704/2, pOut += 1024/2) {
memcpy(pOut, pIn, p);
}
// fill U rect
for (int y = 0, p = min(704/2, 1024/2);
y < 576/2;
l++, pIn += 704/2, pOut += 1024/2) {
memcpy(pOut, pIn, p);
}

http://msdn.microsoft.com/en-us/library/dd206750(v=vs.85).aspx#yv12
0 new messages