View Full Version : MPEG2 question.
redeemer-dk
10th April 2003, 22:35
OK. I'm trying to figure the MPEG2 Video format out with the ISO/IEC document 13818-2. I'm having some problems when reading the sequence_header. I have some questions:
Am i correct when i say that the first start_code has to be 0xb3 (sequence_header)?
When i test it with reading an MPEG2 only file (which DVD2AVI can read easily meaning it contains no errors) this is the first 8 bytes:
00 00 01 B3 2D 02 40 33
The first four are OK. The start code prefix + a start code (sequence_header). The next 4 bytes contain (according to the document) this:
horizontal_size_value 12
vertical_size_value 12
aspect_ratio_information 4
frame_rate_code 4
Exactly how am i supposed to read this information? The left of the table says it's uimsbf which is Unsigned integer, most significant bit first. How is that compared to if i read the four bytes into a DWORD and compared to if i just read the whole deal into a struct like this:
sequence_header header;
typedef struct {
unsigned int horizontal_size_value:12;
unsigned int vertical_size_value:12;
unsigned int aspect_ratio_information:4;
unsigned int frame_rate_code:4;
unsigned int bit_rate_value:18;
unsigned int marker_bit:1;
unsigned int vbv_buffer_size_value:10;
unsigned int constrained_parameters_flag:1;
unsigned int load_intra_quantiser_matrix:1;
unsigned char intra_quantiser_matrix[64];
unsigned int load_non_intra_quantiser_matrix:1;
unsigned char non_intra_quantiser_matrix[64];
} sequence_header;
ReadFile(hFile, &header, sizeof(sequence_header), &dwBytesRead, NULL);
When i do this, none of the values are correct, so i must be doing something wrong.
And also. If i load 136 bytes (size of the sequence_header structure) from byte number 4 (the first byte after B3) and use memcpy to copy it to my struct. All the values are right except horizontal_size_value and vertical_size_value which are 557 and 1024 respectively. Does anyone know what i am doing wrong?
Thanks a bunch!
-Rune Svendsen
ChristianHJW
11th April 2003, 02:56
Is your MPEG2 from a VOB ( DVD ) ?? If so, AR info is stored in the IFO, not in the stream. Often its even set incorrect in the MPEG2 to mislead rippers ...
redeemer-dk
11th April 2003, 08:46
Yes it's from a DVD, i demultiplexed it to get the M2V file. But i've reencoded it with CCE SP so the information should be correct. If I do like I wrote at the end of my previous post, the aspect_ratio_information becomes 3 aswell as the frame_rate_code. Which is 16:9 and 25fps which both are correct.
BlisterBlue
11th April 2003, 23:52
@redeemer-dk:
Yes, seems your doing the binary math wrong. ;) The MPEG2 Format is a Bit-Stream not a Byte-Stream! You have to convert the 4 Byte values after the 'B3' start code to a Bit-Stream. So you get:
Bytes: 2D 02 40 33
Bits: 00101101 00000010 01000000 00110011
Stream: |----HSV----||----VSV----| |AR||FR|
Now grab the first 12 Bits starting from the left and you get '001011010000' for the Horizontal Size Value (HSV) which is '720' decimal and you get '001001000000' for the Vertical Size Value (VSV) which is '576' decimal. And you get '0011' for the Aspect Ratio Information (AR) which is '3' decimal and you also get '0011' for the Frame Rate Code (FR) which is also '3' decimal. It's that easy. ;)
You have to do this kind of Bit-Stream Operations for the whole MPEG2 stream if you want to parse all the information you need and it can get even more difficult as it must not be byte aligned - so you have to create some smart stream parsing routines that loads the appropriate number of bits from the stream (e.g. 12 bits or 4 or whatever) and then you can convert it to decimal values afterwards.
Always remember when dealing with MPEG2 - it's bits - not bytes!
Hope this helps,
BlisterBlue
redeemer-dk
12th April 2003, 15:55
Thanks a lot BlisterBlue! I've written such a routine and it works now, thanks for you help. Although I've run into a problem. I can't figure out how many bits to read into the macroblock_address_increment variable. The ISO document says "1-11" and if i follow all the other places that concerns macroblock_address_increment i can't see a place where they say how many bits to read, just what you use the variable for etc.. Can you clarify that?
Thanks in advance :)
mpucoder
13th April 2003, 00:14
Now you're getting into the real fun part of bitstreams. You have to parse the field according to (in this case) Table B1. All fields have a more wordy description later on that
tell you how to interpret them.
redeemer-dk
14th April 2003, 13:30
I've already looked at Table B-1 (http://www.slimsite.subnet.dk/misc/table-b1.htm), but what i don't understand is how i know the number of bits i should read from the bitstream. It says 1-11, and i can't find anywhere where it says how many bits i actually must read. The table just says what the different values are according to the combination of bits, but how do i know how many bits i should read from the bitstream in the first place?
Thanks in advance.
-Rune Svendsen
mpucoder
14th April 2003, 16:09
You have to parse the field bit by bit. The value of each bit determines how many more bits you need to examine. The same is generally true for Huffman encoding, which is used a lot in MPEG. You do this with a parse tree. For example, if the first bit is a "1" then the parsing is done, and the value is 1. But if the first bit is "0" the field is at least 3 bits long, and you need to examine the next bit. If the second bit is a "1" the field is 3 bits long, but if it's a "0" you need to look at the next bit, etc.
Another way to parse variable length fields is to examine the maximum number of bits, in this case 11, and perform a masked search of the values. The mask is used to block the bits which are not part of a particular table entry. Example (first 4 entries, data is in lower 11 bits)
entry # mask pattern
1 0x400 0x400 (1 bit, value = 1)
2 0x700 0x300 (3 bits, value = 2)
3 0x700 0x200 (3 bits, value = 3)
4 0x780 0x180 (4 bits, value = 4)
You should also be aware that the macroblock_escape, shown as 11 bits, exists only if the 11 bits match the pattern '0000 0001 000', and can occur more than once. If you look at table B-1 you'll see that code listed (as macroblock_escape). The best approach is to start with a variable cleared to zero for the increment and parse looking for macroblock_address_increment. If you get the code '0000 0001 000' add 33 to the variable and parse again.
redeemer-dk
15th April 2003, 16:37
Thanks for your help mpucoder, much appreciated. But i'm facing a problem concerning the parsing of the bits.
According to my program, the four bytes that contain the macroblock_address_increment value are these:
68 D1 83 D4
Which is this in binary: 1101000110100011000001111010100
Now i'm asking; since the format, according to the iso document, is vlclbf, where are the bits i'm going to use located in these bits?
According to my routine for scanning through the bitstream, i'm at a position where there are 26 bits left in the stream. I'm not quite sure what vlclbf is and i can't understand what the ISO document says about it. The bytes i have above are from a HEX editor, where 68 is the first byte and the next bytes are followed by it. But if the format is vlclbf (or bslbf as for the macroblock_escape) where are the bits i'm going to use located?
Thanks in advance.
-Rune Svendsen
mpucoder
15th April 2003, 17:45
IF those bytes are the very beginning of the macroblock, then the macroblock_address_increment is 2. The bits that define the value are "011" (btw, when working with bitstreams on paper, don't remove leading zeroes) If you look at table B-1 you will notice that no other value has "011" in the first three bits (left to right, which is what vlclbf says - variable length code, left bit first)
redeemer-dk
15th April 2003, 19:23
Works perfectly. I will continue coding now :)
redeemer-dk
30th April 2003, 18:33
I have (yet) another question:
I'm in the block() procedure. My question is regarding the First DCT coefficient of a non-intra block. According to the ISO document, in this case table B-14 is modified by NOTE 2 and NOTE 3. I understand NOTE 2 but i'm a bit unclear on NOTE 3. Does it mean that this code is the only code possible that you can read when you're reading the first coefficient of a non-intra block?
Thankyou in advance.
-Rune Svendsen
mpucoder
30th April 2003, 23:16
No, it means the code 1s is used where 11s would be used for other coefficients. This is a special case to save one bit. As Note 2 and the text in the description says, End Of Block shall not be the only code for the block, therefore the code 10 can not appear first, so 1s is not ambiguous. All the other codes (except 11s, which should be interpretted as 11 and part of another code in this case) can be received.
redeemer-dk
16th May 2003, 18:34
Thankyou mpucoder :)
OK. So now I have successfully decoded some blocks from the bitstream and I would like to output them to the screen, but i have no idea how to do it. I have the iDCT'd values but i don't know what to do with them...
Thanks in advance.
-Rune Svendsen
mpucoder
17th May 2003, 03:54
This is an excerpt from a program a mine (before anyone asks).
hdcDest = BeginPaint( hDlg, &ps ) ;
SetStretchBltMode(hdcDest, STRETCH_DELETESCANS ) ;
StretchBlt( hdcDest, 0, 0, wWidth, wHeight,
hdcMem[VwrNumber], 0, 0, wMemX[VwrNumber], wMemY[VwrNumber], SRCCOPY ) ;
DeleteDC( hdcDest ) ;
EndPaint( hDlg, &ps ) ;
hDlg is the handle of the window created for the image.
hdcMem[] is an array of buffers, wMemX[] and wMemY[] are the spatial dimensions.
All this is done for WM_PAINT
fengtao
17th May 2003, 04:03
try this:
hdcDest = BeginPaint( hDlg, &ps ) ;
hOldMode = SetStretchBltMode(hdcDest, STRETCH_DELETESCANS ) ;
StretchBlt( hdcDest, 0, 0, wWidth, wHeight,
hdcMem[VwrNumber], 0, 0, wMemX[VwrNumber], wMemY[VwrNumber], SRCCOPY ) ;
SetStretchBltMode(hdcDest, hOldMode ) ;
EndPaint( hDlg, &ps ) ;
mpucoder
17th May 2003, 04:08
fengtao - get a lot of memory leaks?
fengtao
17th May 2003, 04:41
There is no memory leaks, you don't need DeleteDC( hdcDest ).
redeemer-dk
17th May 2003, 13:25
but how do i arrange the different values in my buffer?
I have 4 two dimensional arrays of luminance data and 2 two dimensional arrays of chrominance data... how do i combine these values in the buffer to output it on the screen?
fengtao
17th May 2003, 17:07
Hi redeemer-dk,
I don't know about luminance data and chrominance data, but I think you should transfer it to RGB data and fill it in the memory DC at first.
Best Regards,
Fengtao
redeemer-dk
17th May 2003, 17:15
That's what i originally planned to do... but i don't know how to do it...
The formulas I've found for the conversion are this:
(16-235)
R = Y + 1.371(Cr-128)
G = Y - 0.698(Cr-128) - 0.336(Cb-128)
B = Y + 1.732(Cb-128)
(0-255)
R = 1.164(Y-16)+1.596(Cr-128)
G = 1.164(Y-16)-0.813(Cr-128) - 0.392(Cb-128)
B = 1.164(Y-16)+2.017(Cb-128)
But which values should i use? I have four arrays with luminance data (Y) and two arrays of chrominance data (Cb). How do i combine these buffer cause according to the forumlas i only need ONE luminance value and ONE chrominance value, not four and two...
Thanks in advance...
-Rune SVendsen
sh0dan
17th May 2003, 17:58
16-235 - even though this is a BIG issue of discussion :rolleyes:
redeemer-dk
17th May 2003, 18:13
but my question is actually regarding what i should do when i have four buffers with luminance data and two buffers with chrominance data... should i combine these buffers somehow to get the final values or which values should i insert in the formula?
sh0dan
17th May 2003, 23:49
What are you going to do to the data afterwards?
redeemer-dk
19th May 2003, 19:17
I've misunderstood something, that's probably the reason you guys didn't get my question :) Now my new question is, how do i convert the 4:2:0 data to 4:4:4 data so i can recreate the four 8x8 blocks inside the 16x16 macroblock?
Thanks again :)
-Rune Svendsen
sh0dan
19th May 2003, 19:45
Judging from what I think you attempt to do, that shouldn't be necessary. You don't need 4:4:4 to reconstruct all four blocks within a macroblock - you should still be able to do this in 4:2:0. You should be able to decode MPEG2 completely to 4:2:0.
Otherwise it's just a matter of chroma upsampling. For your _first_ test you could simply copy chroma from the 4:2:0 into the four 4:4:4 chroma pixels - it is not correct, but for some tests it should be enough. Otherwise search for "chroma upsampling" - it has been discussed intensely in the Avisynth Dev. forum.
The DVD2AVI / MPEG2DEC sources are complete MPEG2 decoders and should provide you with the information you need. Also the XviD source has many similarities (when dealing with decoding).
redeemer-dk
30th May 2003, 19:01
I've now come to the stage where i need to find bugs in my decoding routine (and there's a lot of them). Here is my decoded picture compared to the original:
http://www.chasecarter.ca/redweb/Redeemer/compare.htm ( Don't laugh :) )
I just wanted to check if any one you who have developed an MPEG2 decoder has experienced similar bugs and found out what it was. The most distinct errors are that some slices get a shade of some color, like slice number 6 has a green shade and slice number 11 has a red shade. The blocks also look strange and doesen't "blend" in with each other as nice as with the real picture. The edges are very visible.
Thanks in advance!
-Rune Svendsen
redeemer-dk
24th June 2003, 17:53
Hello again.
I'm getting to the chroma upsampling part now. I've read about it a couple of places and I just want to make sure I've understood it right. Here's a picture of a macroblock. The X's are luma samples and the circles are chroma samples. I've numbered some of the luma and chroma samples to make it easier to explain. Is this the correct method?
http://www.chasecarter.ca/redweb/Redeemer/example.gif
Luma1 = Chroma1
Luma2 = Chroma1
Luma3 = (Chroma1+Chroma2) / 2
Luma4 = (Chroma1+Chroma2) / 2
Luma5 = Chroma2
Luma6 = Chroma2
Etc...
Is this correct?
Thanks in advance,
-Rune Svendsen
mpucoder
24th June 2003, 18:24
Close - chroma value 1 applies to the pixels with luma values 1, 2, 3, and 4. There is no blending of chroma values.
redeemer-dk
24th June 2003, 18:30
I see, thankyou.
fccHandler
24th June 2003, 19:35
Originally posted by mpucoder
Close - chroma value 1 applies to the pixels with luma values 1, 2, 3, and 4. There is no blending of chroma values.
:confused: That's correct when the chroma samples are between the luma samples, but the MPEG-2 spec redefined the positions as shown in the diagram. Chroma 1 is horizontally aligned with Luma 1 & 2, and Chroma 2 is horizontally aligned with Luma 5 & 6, therefore the chroma value for Luma 3 & 4 should be the average of Chroma 1 and Chroma 2.
redeemer-dk
27th June 2003, 01:29
Thankyou both. But... am I missing something here?
I'm pretty sure I'm doing the right thing here... but my results are VERY blocky and no way near the DVD2AVI results... (does DVD2AVI use any filtering?)
Here is a comparison of my decoded picture versus DVD2AVI's decoded picture: http://www.chasecarter.ca/redweb/Redeemer/compare.htm
Here's my (simplified) routine. (Here I just copy chroma instead of averaging but that shouldn't make a big difference):
for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 16; x++)
{
b = (int)( 1.164*(luminancesrc[(y*16)+x] - 16) + 1.596*(crsrc[((int)(y/2) * 8) + ((int)(x/2))] - 128) );
g = (int)( 1.164*(luminancesrc[(y*16)+x] - 16) - 0.813*(crsrc[((int)(y/2) * 8) + ((int)(x/2))] - 128) - 0.392*(cbsrc[((int)(y/2) * 8) + ((int)(x/2))] - 128) );
r = (int)( 1.164*(luminancesrc[(y*16)+x] - 16) + 2.017*(cbsrc[((int)(y/2) * 8) + ((int)(x/2))] - 128) );
}
}
This is my basic routing for creating a 16x16 rgb block.
The luminancesrc buffer is a two-dimensional 16 by 16 buffer containing the luminance data. The crsrc and cbsrc buffers are two two-dimensional 8 by 8 buffers containing chrominance data.
BTW, when I combine my luminance data (the four 8 by 8 buffers) i combine them like this and create a 16 by 16 buffer, is this correct?:
_____
|1|2|
|3|4|
So that the first buffer derived from the stream is in the upper left corner of the 16 by 16 matrix, the second buffer is in the upper right corner, the third buffer is in the lower left corner and the fourth and last buffer is in the lower right corner.
Can anyone think of any other reasons why my image is so blocky?
Thanks all!
-Rune Svendsen
fccHandler
27th June 2003, 03:01
Just an impression; it looks to me like a fault in the IDCT.
mpucoder
27th June 2003, 03:26
brings back memories of when I wrote a jpg decoder. There are a number of things that it could be - did you make sure of the coefficient order (zigzag or alternate)? here (http://www.bretl.com/mpeghtml/zigzag.HTM) is a handy page I ran across some time ago.
Scaling is another thing that can cause exagerated contrast. Also using the correct quantiser matrix for each component.
redeemer-dk
28th June 2003, 17:26
Hmmm, I feel like I'm missing something here... It's like I'm missing a step in the decoding process somewhere... as far as i can see nothing is wrong with my code... Here's what i do with each block in the decoding process when decoding a macroblock:
1. Variable Length Decoding and put the product in the QFS buffer.
2. Inverse Scan as follows:
alternate_scan = picture_coding_extension_struct.alternate_scan;
for (v=0; v<8; v++)
for (u=0; u < 8; u++)
QF[v][u] = QFS[scan[alternate_scan][v][u]];
And i do the same with the weighting matrices.
3. Inverse Quantisation:
Derive the DC coefficient as follows:
Fmarkmark[0][0] = intra_dc_mult * QF[0][0];
And the AC coefficients as follows:
quantiser_scale_value = quantiser_scale[picture_coding_extension_struct.q_scale_type][slice_struct.quantiser_scale_code];
for (v=0; v<8;v++)
{
for (u = (v==0 ? u : 0);u<8;u++) //if v==0 then u is the alue determined above, else it is 0. (this is done because the Fmarkmark[0][0] value has already been found)
{
if (macroblock_modes_struct.macroblock_intra == 1)
{
Fmarkmark[v][u] = ((__int64)(2 * QF[v][u]) * W[w][v][u] * quantiser_scale_value) / 32;
}
else
{
Fmarkmark[v][u] = ((__int64)(2 * QF[v][u] + sign(QF[v][u])) * W[w][v][u] * quantiser_scale_value) / 32;
}
}
}
Then i perform Saturation and Mismatch Control as defined in the ISO document.
And end up with the data in the F[8][8] buffer.
At the end i pass the data from F into DVD2AVI's REF_IDCT() function.
And then convert it to RGB with my function as stated in the above post.
I've checked these steps and they all appear to be working properly:
Inverse scan (of both the QF buffer and the weighting matrices and the scanning order is also correct)
Inverse quantisation (It seems I'm doing the same as stated in the ISO document)
I've also discovered that the higher the values in the weighting matrix are, the more blocky the final product becomes:
Weighting Matrix Compare (http://www.chasecarter.ca/redweb/Redeemer/matrix-compare.htm)
Are you guys running out of possible solutions as well as me?
I hope not.. I'll continue struggling with it, i hope you have some input...
Thanks in advance,
-Rune Svendsen
fccHandler
28th June 2003, 20:23
One very important step you didn't mention is "motion compensation", i.e., adding forward/backward prediction data. But surely you didn't forget to do that... ;)
redeemer-dk
28th June 2003, 20:44
Actually i'm not that far yet. I've only reached decoding of intra-coded pictures, they don't require any motion compensation right?
fccHandler
29th June 2003, 00:20
Right.
Your code seems quite original, so it's difficult for me to follow because most of the implementations I've seen (FlasK, Mpeg2dec3, and my own mod of VirtualDub) are heavily based on the MSSG reference decoder. But it's great that you are doing this your own way!
As far as I can tell all of your steps are correct. But I noticed that your block decoder is adding something called "sign(QF[v][u])" to the coefficients of non-intra blocks. However, this value is omitted from intra blocks. Is that an oversight, or am I just misinterpreting the code?
redeemer-dk
29th June 2003, 00:41
That should be correct...
ISO/IEC 13818-2. Page 85, 7.4.2.3 Recontruction formulae
F’’[v][u] = ((2 * QF[v][u] + k ) * W[w][v][u] * quantiser _ scale) / 32
where :
k =
0 for intra blocks
Sign(QF[v][u]) for non - intra blocks
BTW, do you have any experience with the DVD2AVI code? I'm looking at it right now, and i see one great difference from my code. When resetting the DC predictors, dc_dct_pred, DVD2AVI resets them to 0. I'm resetting them to 512 as stated in the ISO document (if intra_dc_precision equals 2).
ISO/IEC 13818-2. Page 78, 7.2.1 DC coefficients in intra blocks.
I've tried resetting them to 0 in my code but that just results to a green picture...
fccHandler
29th June 2003, 01:26
Originally posted by redeemer-dk
BTW, do you have any experience with the DVD2AVI code? I'm looking at it right now, and i see one great difference from my code. When resetting the DC predictors, dc_dct_pred, DVD2AVI resets them to 0. I'm resetting them to 512 as stated in the ISO document (if intra_dc_precision equals 2).
I haven't seen the DVD2AVI code, but it's likely to be based on the MSSG reference which also resets the predictors to zero. But in MSSG's case, the block decoding functions correct for it by shifting the DC coefficient left by (3-intra_dc_precision) bits before decoding the block.
This is one of many ways in which the MSSG code differs from the ISO document, but its output is still compliant AFAIK. Any other differences are presumably due to someone's desire to tweak a little extra speed into the reference code.
redeemer-dk
29th June 2003, 02:33
The DVD2AVI code also has that line:
bp[0] = val << (3-intra_dc_precision);
But i don't think that can replace resetting the predictors to 512. This is instead of multiplying by intra_dc_mult:
Thus; F’’[0 ][0] = intra_ dc_ mult * QF[0][0]
-Page 82, 7.4.1 Intra DC coefficient
BTW i just found the bug in my code that made the picture so blocky. It was a bug that made the sign of the AC coefficients alternate between negative and positive.
It's still a little bit blocky, but I'll look into that tomorrow, 3:30 AM here so I'm going to bed :)
Thanks for your help.
-Rune Svendsen
redeemer-dk
1st July 2003, 01:47
I have a couple of questions about motion search compensation.
I'm decoding a P picture and in macroblock number two pattern_code[0] equals 0.
Then I do this: Read the motion vectors from the stream and decode them according to 7.6.3.1 of the MPEG2 standard. First of all, now I have two motion vectors for both the horizontal and the vertical part:
//horizontal
vector[0][0][0]
vector[1][0][0]
//vertical
vector[0][0][1]
vector[1][0][1]
Why do I need two?
Second, when I have decoded the motion vectors correctly and I'm in the first block of a macroblock, like in the figure below, do I then just copy the 8 by 8 luma values from the reference frame (the ones inside the square in the figure) to the block I'm currently decoding?
Does the motion vector refer to the upper right corner of the block?
Figure: http://www.chasecarter.ca/redweb/Redeemer/motion_pred.gif
-I've reached the point marked by the single x at the right in the "current frame to be decoded". The decoded motion vector for that block is the one at the right of the "current frame to be decoded".
I still have a lot of question but I hope they will be clarified.
Does anyone have any documents that explain the motion search compensation step a bit more thorough the the ISO standard?
Thanks a lot!
-Rune Svendsen
fccHandler
1st July 2003, 18:23
I guess this means you got I-pictures working. :D
Originally posted by redeemer-dk
Why do I need two?
One set for each field? Or one set each for top and bottom half (16x8 prediction)? It depends on the video structure. Motion compensation is awfully complex in MPEG-2 video.
Does the motion vector refer to the upper right corner of the block?
Yes, except the motion vectors can have half-pel precision.
Does anyone have any documents that explain the motion search compensation step a bit more thorough the the ISO standard?
The ISO standard should be plenty thorough. The only other thing I can suggest is to look at lots of source code, or search (http://www.google.com) for some illustrations on the web.
redeemer-dk
4th July 2003, 00:54
Yup, got the I-frames working :)
I have a couple more questions...
When decoding a block where macroblock_intra equals 0 but where pattern_code[i] equals one, what am I supposed to do with the decoded values? Here's an example of the quantised values:
F
0x00421518 short (* F)[8]
[0]: 0x00421518 short (* F)[8]
[1]: 0x00421528
[2]: 0x00421538
[3]: 0x00421548
[4]: 0x00421558
[5]: 0x00421568
[6]: 0x00421578
[7]: 0x00421588
F[0]
0x00421518 short (* F)[8]
[0]: 0
[1]: 0
[2]: 0
[3]: 0
[4]: 0
[5]: 0
[6]: 0
[7]: 0
F[1]
0x00421528
[0]: 0
[1]: 0
[2]: 0
[3]: 0
[4]: -3
[5]: 0
[6]: 0
[7]: 0
F[2]
0x00421538
[0]: 0
[1]: 0
[2]: -8
[3]: 3
[4]: 0
[5]: 0
[6]: 0
[7]: 0
F[3]
0x00421548
[0]: 3
[1]: 3
[2]: -3
[3]: 0
[4]: 0
[5]: 0
[6]: 0
[7]: 0
F[4]
0x00421558
[0]: 3
[1]: 0
[2]: -4
[3]: 0
[4]: 0
[5]: 0
[6]: 0
[7]: 0
F[5]
0x00421568
[0]: 0
[1]: 0
[2]: 0
[3]: 0
[4]: 0
[5]: 0
[6]: 0
[7]: 0
F[6]
0x00421578
[0]: 0
[1]: 4
[2]: 0
[3]: 0
[4]: 0
[5]: 0
[6]: 0
[7]: 0
F[7]
0x00421588
[0]: 0
[1]: 0
[2]: 0
[3]: 0
[4]: 0
[5]: 0
[6]: 0
[7]: 1
What am I supposed to do with these values? Should i perform iDCT on them? When i do that i get strange values like these:
f[0]
0x004221c0 "ÿÿüþÿÿÿÿ"
[0]: 255 'ÿ'
[1]: 1 '␁'
[2]: 2 '␂'
[3]: 3 '␃'
[4]: 3 '␃'
[5]: 3 '␃'
[6]: 255 'ÿ'
[7]: 252 'ü'
f[1]
0x004221c8 "þÿÿÿÿ"
[0]: 254 'þ'
[1]: 255 'ÿ'
[2]: 255 'ÿ'
[3]: 255 'ÿ'
[4]: 255 'ÿ'
[5]: 1 '␁'
[6]: 1 '␁'
[7]: 0
So I'm wondering if I'm just supposed to add the values to the predicted values without performing iDCT on them.
Another question: When decoding skipped macroblocks, should i just copy the values from the blocks from the macroblock in the reference picture at the same position as the macroblock being decoded? And also, should I do this just when I've found out that the next macroblock is a skipped macroblock (when decoding macroblock_address_increment)? Is there no information about the skipped macroblock coded in the stream (the values from the the macroblock_modes function)?
Thanks in advance,
-Rune Svendsen
fccHandler
4th July 2003, 17:33
Originally posted by redeemer-dk
What am I supposed to do with these values? Should i perform iDCT on them?
I still have some trouble following your code, but I know that any macroblock with its pattern_code set will have IDCT performed on it, regardless of whether it's an intra or non-intra block. Why do you say the values look strange?
Is there no information about the skipped macroblock coded in the stream (the values from the the macroblock_modes function)?
IIRC there is none. But the blocks aren't simply copied, they get the same motion compensation that non-skipped blocks get, except there are no explicit motion vectors coded for them. If the frame is a P-picture the forward prediction vectors get reset to zero, otherwise I think a skipped block in a B-picture will use the same vectors which the previous block used.
redeemer-dk
4th July 2003, 19:12
Thankyou.
I say the values look strange because of the large contrast (values like 1 followed by 255), but i guess it could happen. I'll try to decode them that way and see the result.
About the skipped macroblock issue, I got it now :) Thanks man.
-Rune Svendsen
fccHandler
4th July 2003, 21:01
Originally posted by redeemer-dk
I say the values look strange because of the large contrast (values like 1 followed by 255)
Not if you think of them as signed numbers (255 is actually -1). ;)
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.