Wednesday, March 05, 2008

Video Rendering downstream Filter Problem

I am decoding an MPEG2 video stream with resolution of 704x480 to the YUY2 format type (using ffmpeg).
If I use the equation:
lSampleSize = pVIH->bmiHeader.biWidth * pVIH->bmiHeader.biBitCount * pVIH->bmiHeader.biHeight / 8
I get a sample size of 675840 bytes.
This is the same size of data I am getting from my decode routine for the resulting YUY2 image. By intercepting other samples coming from other decoders, it is apparent that the correct size of the media sample, when calling SetActualDataLength should be 737280. This number can be calculating from the same equation above if the width is incremented to a number divisible by 128. I've discovered enough to know that this is due to the stride requirement of the VMR.
My question is this... How do I know the stride requirement as it surely cannot always be 128?
And more importantly, how would I go about populating a DirectShow media sample buffer from a pointer to the raw bytes of YUY2 data which is 675840 bytes in length?
Result :
--------------
When your output pin connects to the video renderer's input pin, after CheckMediaType() and before DecideBufferSize(), the video renderer will call your QueryAccept() method with the adjusted biWidth (that is, biWidth will be the stride and rcSource.right-rcSource.left will be the width). You need to override QueryAccept() and save the adjusted media type, so you will know the correct stride and sample size (which you will need right after in DecideBufferSize()).
> And more importantly, how would I go about populating a > DirectShow media sample buffer from a pointer to the raw > bytes of YUY2 data which is 675840 bytes in length?
You copy 1 scanline at a time:
for(y = 0; y < height; y++)
{
source = buffer + y * width; target = sample + y * stride; memcpy(target,source,width*sizeof(pixel));
}

No comments: