+ p_outpic = filter_NewPicture( p_filter );
+ if( !p_outpic )
+ {
+ picture_Release( p_pic );
+ return NULL;
+ }
+
+ const int i_visible_pitch = p_pic->p->i_visible_pitch>>1; /* In fact it's i_visible_pixels */
+ const int i_visible_lines = p_pic->p->i_visible_lines;
+
+ const uint8_t *p_in = p_pic->p->p_pixels+i_y_offset;
+ const uint8_t *p_in_u = p_pic->p->p_pixels+i_u_offset;
+ const uint8_t *p_in_v = p_pic->p->p_pixels+i_v_offset;
+ const int i_in_pitch = p_pic->p->i_pitch;
+
+ uint8_t *p_out = p_outpic->p->p_pixels+i_y_offset;
+ uint8_t *p_out_u = p_outpic->p->p_pixels+i_u_offset;
+ uint8_t *p_out_v = p_outpic->p->p_pixels+i_v_offset;
+ const int i_out_pitch = p_outpic->p->i_pitch;
+
+ const int i_line_center = i_visible_lines>>1;
+ const int i_col_center = i_visible_pitch>>1;
+
+ if( p_sys->p_motion != NULL )
+ {
+ int i_angle = motion_get_angle( p_sys->p_motion );
+ store_trigo( p_sys, i_angle / 20.f );
+ }
+
+ int i_sin, i_cos;
+ fetch_trigo( p_sys, &i_sin, &i_cos );
+
+ int i_col, i_line;
+ for( i_line = 0; i_line < i_visible_lines; i_line++ )
+ {
+ for( i_col = 0; i_col < i_visible_pitch; i_col++ )
+ {
+ int i_line_orig;
+ int i_col_orig;
+ /* Handle "1st Y", U and V */
+ i_line_orig = i_line_center +
+ ( ( i_sin * ( i_col - i_col_center )
+ + i_cos * ( i_line - i_line_center ) )>>12 );
+ i_col_orig = i_col_center +
+ ( ( i_cos * ( i_col - i_col_center )
+ - i_sin * ( i_line - i_line_center ) )>>12 );
+ if( 0 <= i_col_orig && i_col_orig < i_visible_pitch
+ && 0 <= i_line_orig && i_line_orig < i_visible_lines )
+ {
+ p_out[i_line*i_out_pitch+2*i_col] = p_in[i_line_orig*i_in_pitch+2*i_col_orig];
+ i_col_orig /= 2;
+ p_out_u[i_line*i_out_pitch+2*i_col] = p_in_u[i_line_orig*i_in_pitch+4*i_col_orig];
+ p_out_v[i_line*i_out_pitch+2*i_col] = p_in_v[i_line_orig*i_in_pitch+4*i_col_orig];
+ }
+ else
+ {
+ p_out[i_line*i_out_pitch+2*i_col] = 0x00;
+ p_out_u[i_line*i_out_pitch+2*i_col] = 0x80;
+ p_out_v[i_line*i_out_pitch+2*i_col] = 0x80;
+ }
+
+ /* Handle "2nd Y" */
+ i_col++;
+ if( i_col >= i_visible_pitch )
+ break;
+
+ i_line_orig = i_line_center +
+ ( ( i_sin * ( i_col - i_col_center )
+ + i_cos * ( i_line - i_line_center ) )>>12 );
+ i_col_orig = i_col_center +
+ ( ( i_cos * ( i_col - i_col_center )
+ - i_sin * ( i_line - i_line_center ) )>>12 );
+ if( 0 <= i_col_orig && i_col_orig < i_visible_pitch
+ && 0 <= i_line_orig && i_line_orig < i_visible_lines )
+ {
+ p_out[i_line*i_out_pitch+2*i_col] = p_in[i_line_orig*i_in_pitch+2*i_col_orig];
+ }
+ else
+ {
+ p_out[i_line*i_out_pitch+2*i_col] = 0x00;
+ }
+ }
+ }
+
+ return CopyInfoAndRelease( p_outpic, p_pic );