- uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
- uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
- uint8_t *next = &pv->ref[2][plane][y*ref_stride];
- uint8_t *dst2 = &dst[plane][y*w];
-
- yadif_filter_line( dst2, prev, cur, next, plane, parity ^ tff, y, pv );
+ /* This line gets yadif filtered. It is the bottom field
+ when TFF and vice-versa. It's the field that gets
+ filtered. Because yadif needs 2 lines above and below
+ the one being filtered, we need to mirror the edges.
+ When TFF, this means replacing the 2nd line with a
+ copy of the 1st, and the last with the second-to-last. */
+ if( y > 1 && y < ( h -2 ) )
+ {
+ /* This isn't the top or bottom, proceed as normal to yadif. */
+ uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
+ uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
+ uint8_t *next = &pv->ref[2][plane][y*ref_stride];
+ uint8_t *dst2 = &dst[plane][y*w];
+
+ yadif_filter_line( dst2,
+ prev,
+ cur,
+ next,
+ plane,
+ parity ^ tff,
+ y,
+ pv );
+ }
+ else if( y == 0 )
+ {
+ /* BFF, so y0 = y1 */
+ memcpy( &dst[plane][y*w],
+ &pv->ref[1][plane][1*ref_stride],
+ w * sizeof(uint8_t) );
+ }
+ else if( y == 1 )
+ {
+ /* TFF, so y1 = y0 */
+ memcpy( &dst[plane][y*w],
+ &pv->ref[1][plane][0],
+ w * sizeof(uint8_t) );
+ }
+ else if( y == penultimate )
+ {
+ /* BFF, so penultimate y = ultimate y */
+ memcpy( &dst[plane][y*w],
+ &pv->ref[1][plane][ultimate*ref_stride],
+ w * sizeof(uint8_t) );
+ }
+ else if( y == ultimate )
+ {
+ /* TFF, so ultimate y = penultimate y */
+ memcpy( &dst[plane][y*w],
+ &pv->ref[1][plane][penultimate*ref_stride],
+ w * sizeof(uint8_t) );
+ }