[Ffmpeg-devel] [PATCH] lowres chroma bug
Oleg Metelitsa
oleg
Wed Feb 7 03:30:10 CET 2007
Hello Michael,
>> Please find attached a patch, that solves an
>> "extreme chroma bug" problem in lowres=2 mode
>> reported by Reimar Doffinger 6 months ago:
>>
>> Is the proposed patch OK ?
MN> no because it slows the non lowres code down
Sorry, I did not mean old Reimar's patch which might slow down the non
lowres code. I am trying to propose the new patch that solves the same
problem. I think it must not affect the speed of FFMPEG code because
it really adds only one extra register-to register move instruction.
Could you consider my patch again? If it is not OK, I have another
solution to the "lowres chroma bug" problem.
Please find a patch below and a short explanation why the "lowres
chroma bug" appears.
Index: libavcodec/i386/dsputil_h264_template_mmx.c
===================================================================
--- dsputil_h264_template_mmx.c (revision 7818)
+++ dsputil_h264_template_mmx.c (working copy)
@@ -317,8 +317,9 @@
H264_CHROMA_OP4(%0, %%mm1, %%mm3)
- "movd %%mm1, %0\n\t"
- : "=m" (dst[0]) : "m" (ff_pw_32));
+ "movd %%mm1, %%edx\n\t"
+ "mov %%dx, %0\n\t"
+ : "=m" (dst[0]) : "m" (ff_pw_32): "%edx");
dst += stride;
}
===================================================================
In case of mpeg4 decoding, the "H264_CHROMA_MC2_TMPL" macros is
responsible for handling 2x2 blocks in lowres=2 mode.
The "H264_CHROMA_MC2_TMPL" macros in the original FFMPEG code has the
following problem. It must write a 16-bit word into memory, but it
uses 32-bit movd command for this task.
As a result, a 16-bit word is written into the memory + a "garbage"
16-bit word. The rows in the image are processed from left to right.
It was expected that the garbage will be rewritten in the next
writing circle.
Unfortunately, it does not always work as intended! The codec
processes not one but two rows simultaneously. When we write the
endings of two consecutive rows (say, rows (x) and (x+1)), the
garbage, which is written after the very end of the first row (row
(x)), goes into the very beginning of the second row (row (x+1)). But
the beginning of row (x+1) has been already processed and we are
actually writing garbage on the top of valid image data !
As a result, we have garbage at the beginning of every second row of
an image.
There are 3 possible ways to solve the problem:
1) See the new proposed patch above. It works in the following way: I
changed a 32-bit movd instruction to a 16-bit mov. As a result there
will be no garbage written in the picture any more.
2) We can add to our 16-bit another 16 bit that were can read from
picture and than write 16+16=32 bit. I tried this solution too, but it
was slower than solution 1)
3) We can add two extra pixels to image in lowres=2 mode:
image_stride = image_width + 2
chroma_stride = image_width/2 + 2
Then the garbage will be written to those extra (dummy) pixels rather
than to the beginning of the next row.
The last solution is also OK, and I can send the patch containing 3)
if you like.
Best regards,
Oleg.
More information about the ffmpeg-devel
mailing list