static void FilterI422( vout_thread_t *p_vout, const picture_t *p_pic, picture_t *p_outpic ) { int i_index; switch( p_vout->p_sys->i_mode ) { case TRANSFORM_MODE_180: case TRANSFORM_MODE_HFLIP: case TRANSFORM_MODE_VFLIP: /* Fall back on the default implementation */ FilterPlanar( p_vout, p_pic, p_outpic ); return; case TRANSFORM_MODE_90: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { int i_pitch = p_pic->p[i_index].i_pitch; uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_out = p_outpic->p[i_index].p_pixels; uint8_t *p_out_end = p_out + p_outpic->p[i_index].i_visible_lines * p_outpic->p[i_index].i_pitch; if( i_index == 0 ) { for( ; p_out < p_out_end ; ) { uint8_t *p_line_end; p_out_end -= p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; p_line_end = p_in + p_pic->p[i_index].i_visible_lines * i_pitch; for( ; p_in < p_line_end ; ) { p_line_end -= i_pitch; *(--p_out_end) = *p_line_end; } p_in++; } } else /* i_index == 1 or 2 */ { for( ; p_out < p_out_end ; ) { uint8_t *p_line_end, *p_out_end2; p_out_end -= p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; p_out_end2 = p_out_end - p_outpic->p[i_index].i_pitch; p_line_end = p_in + p_pic->p[i_index].i_visible_lines * i_pitch; for( ; p_in < p_line_end ; ) { uint8_t p1, p2; p_line_end -= i_pitch; p1 = *p_line_end; p_line_end -= i_pitch; p2 = *p_line_end; /* Trick for (x+y)/2 without overflow, based on * x + y == (x ^ y) + 2 * (x & y) */ *(--p_out_end) = (p1 & p2) + ((p1 ^ p2) / 2); *(--p_out_end2) = (p1 & p2) + ((p1 ^ p2) / 2); } p_out_end = p_out_end2; p_in++; } } } break; case TRANSFORM_MODE_270: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { int i_pitch = p_pic->p[i_index].i_pitch; uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_out = p_outpic->p[i_index].p_pixels; uint8_t *p_out_end = p_out + p_outpic->p[i_index].i_visible_lines * p_outpic->p[i_index].i_pitch; if( i_index == 0 ) { for( ; p_out < p_out_end ; ) { uint8_t *p_in_end; p_in_end = p_in + p_pic->p[i_index].i_visible_lines * i_pitch; for( ; p_in < p_in_end ; ) { p_in_end -= i_pitch; *p_out++ = *p_in_end; } p_out += p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; p_in++; } } else /* i_index == 1 or 2 */ { for( ; p_out < p_out_end ; ) { uint8_t *p_in_end, *p_out2; p_in_end = p_in + p_pic->p[i_index].i_visible_lines * i_pitch; p_out2 = p_out + p_outpic->p[i_index].i_pitch; for( ; p_in < p_in_end ; ) { uint8_t p1, p2; p_in_end -= i_pitch; p1 = *p_in_end; p_in_end -= i_pitch; p2 = *p_in_end; /* Trick for (x+y)/2 without overflow, based on * x + y == (x ^ y) + 2 * (x & y) */ *p_out++ = (p1 & p2) + ((p1 ^ p2) / 2); *p_out2++ = (p1 & p2) + ((p1 ^ p2) / 2); } p_out2 += p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; p_out = p_out2; p_in++; } } } break; default: break; } }
static void FilterYUYV( vout_thread_t *p_vout, const picture_t *p_pic, picture_t *p_outpic ) { int i_index; int i_y_offset, i_u_offset, i_v_offset; if( GetPackedYuvOffsets( p_pic->format.i_chroma, &i_y_offset, &i_u_offset, &i_v_offset ) != VLC_SUCCESS ) return; switch( p_vout->p_sys->i_mode ) { case TRANSFORM_MODE_VFLIP: /* Fall back on the default implementation */ FilterPlanar( p_vout, p_pic, p_outpic ); return; case TRANSFORM_MODE_90: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { int i_pitch = p_pic->p[i_index].i_pitch; uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_out = p_outpic->p[i_index].p_pixels; uint8_t *p_out_end = p_out + p_outpic->p[i_index].i_visible_lines * p_outpic->p[i_index].i_pitch; int i_offset = i_u_offset; int i_offset2 = i_v_offset; for( ; p_out < p_out_end ; ) { uint8_t *p_line_end; p_out_end -= p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; p_line_end = p_in + p_pic->p[i_index].i_visible_lines * i_pitch; for( ; p_in < p_line_end ; ) { p_line_end -= i_pitch; p_out_end -= 4; p_out_end[i_y_offset+2] = p_line_end[i_y_offset]; p_out_end[i_u_offset] = p_line_end[i_offset]; p_line_end -= i_pitch; p_out_end[i_y_offset] = p_line_end[i_y_offset]; p_out_end[i_v_offset] = p_line_end[i_offset2]; } p_in += 2; { int a = i_offset; i_offset = i_offset2; i_offset2 = a; } } } break; case TRANSFORM_MODE_180: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_in_end = p_in + p_pic->p[i_index].i_visible_lines * p_pic->p[i_index].i_pitch; uint8_t *p_out = p_outpic->p[i_index].p_pixels; for( ; p_in < p_in_end ; ) { uint8_t *p_line_start = p_in_end - p_pic->p[i_index].i_pitch; p_in_end -= p_pic->p[i_index].i_pitch - p_pic->p[i_index].i_visible_pitch; for( ; p_line_start < p_in_end ; ) { p_in_end -= 4; p_out[i_y_offset] = p_in_end[i_y_offset+2]; p_out[i_u_offset] = p_in_end[i_u_offset]; p_out[i_y_offset+2] = p_in_end[i_y_offset]; p_out[i_v_offset] = p_in_end[i_v_offset]; p_out += 4; } p_out += p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; } } break; case TRANSFORM_MODE_270: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { int i_pitch = p_pic->p[i_index].i_pitch; uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_out = p_outpic->p[i_index].p_pixels; uint8_t *p_out_end = p_out + p_outpic->p[i_index].i_visible_lines * p_outpic->p[i_index].i_pitch; int i_offset = i_u_offset; int i_offset2 = i_v_offset; for( ; p_out < p_out_end ; ) { uint8_t *p_in_end; p_in_end = p_in + p_pic->p[i_index].i_visible_lines * i_pitch; for( ; p_in < p_in_end ; ) { p_in_end -= i_pitch; p_out[i_y_offset] = p_in_end[i_y_offset]; p_out[i_u_offset] = p_in_end[i_offset]; p_in_end -= i_pitch; p_out[i_y_offset+2] = p_in_end[i_y_offset]; p_out[i_v_offset] = p_in_end[i_offset2]; p_out += 4; } p_out += p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; p_in += 2; { int a = i_offset; i_offset = i_offset2; i_offset2 = a; } } } break; case TRANSFORM_MODE_HFLIP: for( i_index = 0 ; i_index < p_pic->i_planes ; i_index++ ) { uint8_t *p_in = p_pic->p[i_index].p_pixels; uint8_t *p_in_end = p_in + p_pic->p[i_index].i_visible_lines * p_pic->p[i_index].i_pitch; uint8_t *p_out = p_outpic->p[i_index].p_pixels; for( ; p_in < p_in_end ; ) { uint8_t *p_line_end = p_in + p_pic->p[i_index].i_visible_pitch; for( ; p_in < p_line_end ; ) { p_line_end -= 4; p_out[i_y_offset] = p_line_end[i_y_offset+2]; p_out[i_u_offset] = p_line_end[i_u_offset]; p_out[i_y_offset+2] = p_line_end[i_y_offset]; p_out[i_v_offset] = p_line_end[i_v_offset]; p_out += 4; } p_in += p_pic->p[i_index].i_pitch; p_out += p_outpic->p[i_index].i_pitch - p_outpic->p[i_index].i_visible_pitch; } } break; default: break; } }
/** * It creates multiples pictures from the source one */ static int Filter( video_splitter_t *p_splitter, picture_t *pp_dst[], picture_t *p_src ) { video_splitter_sys_t *p_sys = p_splitter->p_sys; if( video_splitter_NewPicture( p_splitter, pp_dst ) ) { picture_Release( p_src ); return VLC_EGENERIC; } for( int y = 0; y < p_sys->i_row; y++ ) { for( int x = 0; x < p_sys->i_col; x++ ) { const panoramix_output_t *p_output = &p_sys->pp_output[x][y]; if( !p_output->b_active ) continue; /* */ picture_t *p_dst = pp_dst[p_output->i_output]; /* */ picture_CopyProperties( p_dst, p_src ); /* */ for( int i_plane = 0; i_plane < p_src->i_planes; i_plane++ ) { const int i_div_w = p_sys->p_chroma->pi_div_w[i_plane]; const int i_div_h = p_sys->p_chroma->pi_div_h[i_plane]; if( !i_div_w || !i_div_h ) continue; const plane_t *p_srcp = &p_src->p[i_plane]; const plane_t *p_dstp = &p_dst->p[i_plane]; /* */ panoramix_filter_t filter; filter.black.i_right = p_output->filter.black.i_right / i_div_w; filter.black.i_left = p_output->filter.black.i_left / i_div_w; filter.black.i_top = p_output->filter.black.i_top / i_div_h; filter.black.i_bottom = p_output->filter.black.i_bottom / i_div_h; filter.attenuate.i_right = p_output->filter.attenuate.i_right / i_div_w; filter.attenuate.i_left = p_output->filter.attenuate.i_left / i_div_w; filter.attenuate.i_top = p_output->filter.attenuate.i_top / i_div_h; filter.attenuate.i_bottom = p_output->filter.attenuate.i_bottom / i_div_h; /* */ const int i_x = p_output->i_src_x/i_div_w; const int i_y = p_output->i_src_y/i_div_h; assert( p_sys->p_chroma->b_planar ); FilterPlanar( p_dstp->p_pixels, p_dstp->i_pitch, &p_srcp->p_pixels[i_y * p_srcp->i_pitch + i_x * p_srcp->i_pixel_pitch], p_srcp->i_pitch, p_output->i_src_width/i_div_w, p_output->i_src_height/i_div_h, p_sys->p_chroma->pi_black[i_plane], &filter, p_sys->p_lut[i_plane], p_sys->lambdav[i_plane], p_sys->lambdah[i_plane] ); } } } picture_Release( p_src ); return VLC_SUCCESS; }