[FFmpeg-devel] [PATCH] PAFF: Derivation process for chroma motion vector
Jeff Downs
heydowns
Mon Oct 15 18:51:45 CEST 2007
On Mon, 15 Oct 2007, Loren Merritt wrote:
> In MBAFF, the reference list is generated as a list of frames, and then
> split to make fields. So a field pair is always adjacent in the list, and
> ref_index&1 is the parity.
>
> In PAFF, fields may be independently reordered in the list (and even if
> no reordering is used, the default order isn't always the same as
> MBAFF), so use pic->reference&1 instead. But you also need to change
> pic_as_field() to set reference appropriately.
>
> pic->reference&1 could work in MBAFF too, if you set reference
> approriately in fill_mbaff_ref_list().
Loren is right on in his description of the problem.
I glossed over this when I originally wrote the PAFF support.
The attached patch implements the above approach, fixing chroma MV offsets
for PAFF whilst not keeping around a second approach for MBAFF.
I ran both current svn and svn+patch against all MBAFF complaince bit
streams from JVT. Output of ffmpeg is equal w/ and w/out patch.
Benchmarks results of 10 runs each (this was on PAFF content),
Current svn:
User: avg: 22.294 stddev: 0.027 med: 22.306
svn + patch:
User: avg: 22.194 stddev: 0.049 med: 22.177
Suggested commit message:
"Fix chroma mv offsets for PAFF in a way that is compatible with MBAFF by
setting Picture.reference to indicate parity for all Pictures in reference
list"
-------------- next part --------------
Index: libavcodec/h264.c
===================================================================
--- libavcodec/h264.c (revision 10740)
+++ libavcodec/h264.c (working copy)
@@ -1729,7 +1729,7 @@
if(MB_FIELD){
// chroma offset when predicting from a field of opposite parity
- my += 2 * ((s->mb_y & 1) - (h->ref_cache[list][scan8[n]] & 1));
+ my += 2 * ((s->mb_y & 1) - (pic->reference - 1));
emu |= (my>>3) < 0 || (my>>3) + 8 >= (pic_height>>1);
}
src_cb= pic->data[1] + (mx>>3) + (my>>3)*h->mb_uvlinesize;
@@ -2764,11 +2764,12 @@
else hl_decode_mb_simple(h);
}
-static void pic_as_field(Picture *pic, const int bottom){
+static void pic_as_field(Picture *pic, const int parity){
int i;
for (i = 0; i < 4; ++i) {
- if (bottom)
+ if (parity == PICT_BOTTOM_FIELD)
pic->data[i] += pic->linesize[i];
+ pic->reference = parity;
pic->linesize[i] *= 2;
}
}
@@ -2779,7 +2780,7 @@
if (match) {
*dest = *src;
- pic_as_field(dest, parity == PICT_BOTTOM_FIELD);
+ pic_as_field(dest, parity);
dest->pic_id *= 2;
dest->pic_id += id_add;
}
@@ -3133,8 +3134,7 @@
}
h->ref_list[list][index]= *ref;
if (FIELD_PICTURE){
- int bot = pic_structure == PICT_BOTTOM_FIELD;
- pic_as_field(&h->ref_list[list][index], bot);
+ pic_as_field(&h->ref_list[list][index], pic_structure);
}
}
}else{
@@ -3166,9 +3166,11 @@
field[0] = *frame;
for(j=0; j<3; j++)
field[0].linesize[j] <<= 1;
+ field[0].reference = PICT_TOP_FIELD;
field[1] = field[0];
for(j=0; j<3; j++)
field[1].data[j] += frame->linesize[j];
+ field[1].reference = PICT_BOTTOM_FIELD;
h->luma_weight[list][16+2*i] = h->luma_weight[list][16+2*i+1] = h->luma_weight[list][i];
h->luma_offset[list][16+2*i] = h->luma_offset[list][16+2*i+1] = h->luma_offset[list][i];
More information about the ffmpeg-devel
mailing list