View Full Version : Correcting anamorfic AR in home-made MPEG 2 decoder
Magno
25th December 2004, 14:29
First of all, i would like to wish you a merry Christmas and a Happy New Year (although i hope somebody will answer this thread before 2005 ;))
I am developing a MPEG 2 decoder from some months ago till now, and I am finally optimizing it with MMX in order to achieve more than 25 fps on a 1400 MHz Athlon XP. My problem right now is that i don't now how i should convert anamorfic DVD sources into 16:9 display format. To be precise: in anamorfic PAL sources, the MPEG 2 stream encodes 720x576 stretched images which have to be properly converted to a 16:9 resolution to keep the correct aspect ratio, and i don't know whether it is better to convert it to a 1024x576 or 720x405 resolution. The other question is if any of you knows a quick method or algorithm to convert 576 lines into 405. Maybe using DirectDraw as API for displaying would make the conversion by itself?
ĦĦThank you in advance!!
SeeMoreDigital
25th December 2004, 20:47
I assume you are already aware that all Mpeg2 anamorphic video streams are encoded using either 720x480 pixels (for NTSC) or 720x576 pixels (for PAL), whether they have an AR of 4:3 or 16:9.
And in order for the correct AR to be displayed, a DAR signal has to encoded along with the video stream.
Cheers
Magno
25th December 2004, 21:54
Yes, i knew it already ;) Actually, that is the fact that bothers me: how to convert those 576 lines into 405 (in PAL) to get the proper 16:9 aspect ratio (or how to convert 720 pixels per line into 1024 to achieve the same).
And i still can't see any relationship between the display_extension (containing the DAR signal) and the final YUV planes which are decoded: i suppose i should convert those 720x576 planes into a 720x405 and that is what i don't know how. I don't think if i explained myself properly (my english is getting worse as the days go by...): let's think all the decoding process is well done, so i have an array of size 720x576 bytes (each of them is a luminance pixel, for example) containing the whole anamorfic image; if i display that using a SDL overlay surface, i get the video streteched, so i suppose i should do some postprocessing to that array so it become one of with 720x576 pixels containing the video in the proper aspect ratio plus two black zones, 85 lines height each of them; that last step is the one i have the trouble in.
Greetings.
scharfis_brain
25th December 2004, 22:31
please note:
4:3 720x576 has to be displayed as
788x576
and
16:9 720x576 has to be displayed as
1050x576
this is caused due to the
PAR of 1:1.094 for 4:3 and the
PAR of 1:1.459 for 16:9
ITU 601 may tell you more.
the only MPEG-2 Decoder I found so far, that does this in the correct way is the DSCALER MPEG2 video Decoder with the option
use correct aspect ratio enabled.
If you are coding a completely new Decoder, so please try to avoid the mistakes, which the majority of MPEG-2 decoders do...
Magno
25th December 2004, 22:43
Originally posted by scharfis_brain
please note:
4:3 720x576 has to be displayed as
788x576
and
16:9 720x576 has to be displayed as
1050x576
this is caused due to the
PAR of 1:1.094 for 4:3 and the
PAR of 1:1.459 for 16:9
I have read right now SeeMoreDigital's explanation for aspecta ratio and i think the resolutions are 768x576 for 4:3 and 1024x576 in 16:9.
Anyway... how may I change the PAR of the image? Maybe doing horizontal bicubic interpolation over the decoded frame? Maybe telling DirectDraw/SDL to do it for me (I don't know how...)?
SeeMoreDigital
25th December 2004, 22:47
With the regard to the relationships of PAR, DAR, SAR etc, you might find stegre's explanations useful in this thread: -
http://forum.doom9.org/showthread.php?s=&postid=562532#post562532
And in this thread: -
http://forum.doom9.org/showthread.php?s=&threadid=81300
And scharfis_brain is quite correct to draw your attention to the ITU specifications for PAR... However confusing they may be ;)
EDIT: scharfis_brain, I glad you've managed to find "one" Mpeg2 decoder that follows the ITU 601 spec correctly...
Cheers
scharfis_brain
25th December 2004, 23:04
@SMD: why are you quoting the 'one' ?
Should I have known that there are other MPEG2-Decoders offering ITU-PAR/DAR?
Magno
25th December 2004, 23:09
Thanks a lot, SeeMoreDigital, but i think i can't make myself understood... :(
My problem is NOT how to calculate the final resolution, DAR, SAR or PAR, none of that; my problem is how to convert 720x576 image in the proper 1024x576 when the source is anamorphic; Windows GDI objects, SDL surfaces and so on DON'T let me change PAR, so: either DirectDraw lets me or I'll have to do it "manually" using some interpolation, since i don't know how to change PAR in my display device driver.
CCoug83
25th December 2004, 23:15
I am having an issue with anamorphic widescreen as well... I'd appreciate your responses, especially in relation to this MPEG4 Modifier Program. This is my thread. http://forum.doom9.org/showthread.php?s=&threadid=87189
SeeMoreDigital
25th December 2004, 23:39
Originally posted by Magno
... my problem is how to convert 720x576 image in the proper 1024x576 when the source is anamorphic; There's a further problem... because as scharfis_brain has correctly mentioned, a 720x576 anamorphic 16:9 image should actually be resized to 1050 pixels and not 1024 for CRT TV screens :eek:
Cheers
mpucoder
25th December 2004, 23:48
Magno is talking about MPEG-2 on a computer display, I think.
Anyway, I don't know where all these numbers are coming from, and I have all the appropriate standards in front of me.
MPEG-2 16:9 is a display_aspect_ratio. There is no PAR defined in MPEG-2, that's an MPEG-1 thing. For a computer screen with pixel_aspect_ratio of 1:1 Magno has the correct values.
@Magno - As for how to stretch them easily, what language are you using? Windows has a function that is supposed to use the hardware if available, it's called StretchBlt. You need 2 bitmaps for it, one from the display device context, the other a compatible memory device context.
scharfis_brain
25th December 2004, 23:53
@mpucoder:
here is no PAR defined in MPEG-2, that's an MPEG-1 thing. For a computer screen with pixel_aspect_ratio of 1:1 Magno has the correct values.
WTF...
so, do you think that DVD-MPEG2 uses square Pixels (1:1)?
why should MPEG-1 PAR shall differ from MPEG-2 PAR?
352x288 MPEG-1 PAL-VCD has 1.094 PAR
704x576 has the same PAR
and even
720x576
mpucoder
25th December 2004, 23:58
Why do they differ? By definition. The sequence_header aspect_ratio_information was redifined in ISO/IEC 13818-2 (MPEG-2 video) to use display_aspect_ratio.
Magno
25th December 2004, 23:58
That's the point, mpucoder!! :D
I am using Visual C++ 6.0 to program an user interface for parsing MPEG 2 streams, but if i could avoid using MFC graphic objects, it would be great.
I didn't try with "StretchBlt" but i did with "Bitblit" and i didn't get the desired effect; but maybe the problem was I didn't use two bitmaps, but only one, the display device context...
If you could help me a bit further, I would appreciate it greatly :D
mpucoder
26th December 2004, 00:05
BitBlt uses 2 device contexts as well. They are very similar.
BitBlt( hdcDest, 0, 0, 720, 576, hdcMem, 0, 0, SRCCOPY ) ;
becomes
StretchBlt( hdcDest, 0, 0, 1024, 576, hdcMem, 0, 0, 720, 576, SRCCOPY ) ;
scharfis_brain
26th December 2004, 00:05
mpucoder, do you mean the differency of storage of the DAR/PAR of mpeg2 vs. mpeg1
or do you mean their values, too?
SeeMoreDigital
26th December 2004, 00:09
"And we're off!" (again).
But I think I'll leave it up to mpucoder to do the explaining this time!
Cheers
mpucoder
26th December 2004, 00:13
The values have a different meaning in MPEG-2 from MPEG-1
In MPEG-1 they specify a PAR, and there are 14 legitimate values.
In MPEG-2 they specify DAR (or SAR in one case), and have only 4 legitimate values.
But they are stored in exactly the same place in the sequence_header
I didn't become aware of this redefinition until one day I was looking at an MPEG-1 DVD in VobEdit, and it had a "forbidden" value of 12 for aspect_ratio. (12 is NTSC 4:3 in MPEG-1)
scharfis_brain
26th December 2004, 00:24
In MPEG-2 they specify DAR (or SAR in one case), and have only 4 legitimate values.
Ahhh, okay.
I assume, those values are:
1:1
4:3
16:9 and
2.11:1
of which, only the middle two ones are used in the DVD-Standard...
but then, who defines, that 720 is actually more wide than 704?
is it a fixed PAR (defined by ISO or whomsoever)?
One for each TV-Standard (NTSC/PAL)?
according to this: http://www.mir.com/DMG/aspect.html
PAR == SAR?
mpucoder
26th December 2004, 00:37
That's where ITU-601 comes in. It defines the number of samples for either PAL or NTSC to be 720, using a sample rate of 13.5MHz. The rest gets really tricky as you have to determine just how many of those samples are in the 4:3 or 16:9 display area. The timing of NTSC (not sure about PAL) works out to 704 samples are actually in the active area. And then there is overscan - so you can't really get an exact value.
The real important thing is that 704 and 720 are both the same width. 720 is "full 601" while 704 is "full D1". The timing of the pixel clock does not change, only how many (usually wasted) side pixels are encoded.
@Magno - this code fragment may help
hdcDest = BeginPaint( hDlg, &ps ) ;
if (NULL != (hdcMem = CreateCompatibleDC( hdcDest ))) //get a compatible dc
{
hBmp = CreateCompatibleBitmap(hdcDest, 720, 576 ) ; //and a compatible bitmap
hBmp = SelectObject(hdcMem, hBmp) ;
// fill the memory bitmap using setpixel
StretchBlt( hdcDest, 0, 0, 1024, 576,
hdcMem, 0, 0, 720, 576, SRCCOPY ) ;
DeleteObject( SelectObject( hdcMem, hBmp ) ) ;
DeleteDC( hdcMem ) ;
}
EndPaint( hDlg, &ps ) ;
DeleteDC( hdcDest ) ;
Magno
26th December 2004, 00:46
Thanks a lot, mpucoder!!! :D
I am really very grateful for your help.
The following was the code i was using so far:
h_imagen = CreateCompatibleBitmap(pdc->operator HDC(),
info_RGB.biWidth, -info_RGB.biHeight);
SetDIBits( pdc->operator HDC(),
h_imagen,
0, -info_RGB.biHeight,
imagen,
&SurfaceInfo,
DIB_RGB_COLORS);
m_DCMem = CreateCompatibleDC( pdc->operator HDC() );
h_imagen = (HBITMAP)SelectObject( m_DCMem, h_imagen );
BitBlt( pdc->operator HDC(), 0, 0,
info_RGB.biWidth,
-info_RGB.biHeight,
m_DCMem, 0, 0, SRCCOPY );
DeleteObject( SelectObject( m_DCMem, h_imagen ) );
DeleteDC(m_DCMem);
mpucoder
26th December 2004, 00:50
Looks like all you need to do is create 2 more variables to hold the display resolution and then change the BitBLt to StretchBlt.
I should amend my previous post - 704 and 720 are the same width (ie same PAR) with respect to DVD not MPEG-2 in general.
mpucoder
26th December 2004, 01:04
I think I see where those numbers come from now. For NTSC I get different numbers when correcting for the fact that the screen isn't 720x480, but more like 704x486. Is that what these PARs are for?
scharfis_brain
26th December 2004, 01:05
@mpucoder: Thanks for the tip!
I've read a part of the mentioned spec.
It somehow (not obviously!) redirects to mpeg-1 PAR
(1:1.094 for PAL and 1:0.911 for NTSC),
which now seems to be called SAR for MPEG-2.
if 704 and 720 would have the same width, their PAR cannot be the same.
(simple equations...)
704->1024 -> PAR 1.4545
720->1024 -> PAR 1.4222 (wrong)
why is DVD PAR different from MPEG-2 PAR in your opinion?
most of (if not all, I havn't got time to measure all of them)
DVDs I have seen so far are following the ITU specs:
720x576 4:3 DVDs, that needs to be stretched to 788x576 for correct displayment on my 1024x576 screen.
or 720x576 16:9 DVDs, that needed to be stretched to 1050x576.
as alternative option, the decoder may crop away 8 pixels left and right each, an then scale to 768 and 1024 respectively.
only those scalings are correct. everything else will sqeeze the image slightly in horizontal direction by about 2.6 percent
scharfis_brain
26th December 2004, 01:13
@mpucoder:
I'll try to explain, where the PARs (the correct ones!) come from:
our common sense of 4:3 PAL is: 768x576 pixels.
but ITU 601 said, we only need to digitise this 768 pixels long (try to think analogue & temporal, not in pixels) line with only 702 pixels.
this leads to a PAR of 768/702 = 1.094 pixels.
for NTSC it is somehow more difficult.
the original analogue NTSC pixture had 486 active scanlines, making our 4:3 resolution being 648x486 (weird isn't it?)
ITU said, we need to capture 711 pixels to represent the full active line.
that leads to the NTSC PAR: 648:711 = 0.911
or the other way around:
(more easy)
for digital domain, NTSC had been crippled down to 640x480 (for our 4:3 fixed brains ;) )
(mod 16 resolutions!)
then, one needs to digitize 702 pixels....
which leads us again, to a PAR of 640:702 = 0.911
do you remember the 702 form PAL?
do you see the relation?
both, PAL and NTSC share the same horizontal paramters, pixelwise...
so, if one needs to do a conversion, he/she 'only' needs to scale vertically...
mpucoder
26th December 2004, 02:03
The reason I said to consider 704 and 720 the same for DVD-Video is the ITU-601 constraint. The pixel clock does not change, so neither does the pixel geometry. MPEG-2 is more general than that.
mpucoder
26th December 2004, 02:13
OK, we're getting OT here, and I hope Magno got what he wanted.
ITU-601 says 720 samples per line at 13.5MHz.
ITU-470 says an NTSC line is 63.5555 microseconds long, with 10.9 microseconds blanked. That leaves 52.6555 microseconds active, or (53.6555 x 13.5) 710 whole samples in the active region.
The values (again from ITU-470) for 625/50 systems is 64 - 12 = 52 microseconds active. That indeed is 702 samples from the active region.
mpucoder
26th December 2004, 19:27
@Magno - since you already have a DIB you can copy and stretch from the DIB to the device bitmap in one operation.
The StretchDIBits function copies the color data for a rectangle of pixels in a
device-independent bitmap (DIB) to the specified destination rectangle.
If the destination rectangle is larger than the source rectangle, this function
stretches the rows and columns of color data to fit the destination rectangle.
If the destination rectangle is smaller than the source rectangle, this function
compresses the rows and columns by using the specified raster operation.
int StretchDIBits( HDC hdc, // handle of device context
int XDest, // x-coordinate of upper-left corner of dest. rect.
int YDest, // y-coordinate of upper-left corner of dest. rect.
int nDestWidth, // width of destination rectangle
int nDestHeight, // height of destination rectangle
int XSrc, // x-coordinate of upper-left corner of source rect.
int YSrc, // y-coordinate of upper-left corner of source rect.
int nSrcWidth, // width of source rectangle
int nSrcHeight, // height of source rectangle
CONST VOID *lpBits, // address of bitmap bits
CONST BITMAPINFO *lpBitsInfo, // address of bitmap data
UINT iUsage, // usage
DWORD dwRop // raster operation code
);
lpBits
Points to the DIB bits, which are stored as an array of bytes.
lpBitsInfo
Points to a BITMAPINFO structure that contains information about the DIB.
iUsage
Specifies whether the bmiColors member of the BITMAPINFO structure was provided and,
if so, whether bmiColors contains explicit red, green, blue (RGB) values or indices. The
iUsage parameter must be one of the following values:
DIB_PAL_COLORS - The array contains 16-bit indices into the logical palette of the source device context.
DIB_RGB_COLORS - The color table contains literal RGB values.
Magno
26th December 2004, 21:59
I finally made it work using the piece of code you post yesterday; thank you very much again! :D
I was thinking of trying StretchDIBits, but i read somewhere that it is far more slow than SetDIBits + StretchBit.
I will say you something when i try.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.