This is the initial patch for VLC player's polarized 3D support.
将这个patch应用到VLC播放器的源代码中,会多出一个--anaglyph-scheme polarized的3d模式,全屏幕播放视频时,可以支持偏振3D效果。
# use "./vlc --anaglyph-scheme polarized" to start vlc then watch SBS 3d in fullscreen # brought to you by Joyer(collger AT gmail.com) diff --git a/modules/video_filter/anaglyph.c b/modules/video_filter/anaglyph.c index 5e103d4..6968cda 100644 --- a/modules/video_filter/anaglyph.c +++ b/modules/video_filter/anaglyph.c @@ -24,7 +24,7 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif - +#include <math.h> #include <vlc_common.h> #include <vlc_plugin.h> @@ -35,6 +35,7 @@ static int Create(vlc_object_t *); static void Destroy(vlc_object_t *); static picture_t *Filter(filter_t *, picture_t *); static void combine_side_by_side_yuv420(picture_t *, picture_t *, int, int); +static void combine_side_by_side_yuv420_polarized(picture_t *, picture_t *); #define SCHEME_TEXT N_("Color scheme") #define SCHEME_LONGTEXT N_("Define the glasses' color scheme") @@ -51,6 +52,7 @@ enum scheme_e red_cyan, trioscopic, magenta_cyan, + polarized }; static const char *const ppsz_scheme_values[] = { @@ -59,6 +61,7 @@ static const char *const ppsz_scheme_values[] = { "red-cyan", "trioscopic", "magenta-cyan", + "polarized" }; static const char *const ppsz_scheme_descriptions[] = { "pure red (left) pure green (right)", @@ -66,6 +69,7 @@ static const char *const ppsz_scheme_descriptions[] = { "pure red (left) pure cyan (right)", "pure green (left) pure magenta (right)", "magenta (left) cyan (right)", + "polarized lcd" }; vlc_module_begin() @@ -85,7 +89,7 @@ static const char *const ppsz_filter_options[] = { struct filter_sys_t { - int left, right; + int left, right, polarized; }; @@ -116,6 +120,7 @@ static int Create(vlc_object_t *p_this) char *psz_scheme = var_CreateGetStringCommand(p_filter, FILTER_PREFIX "scheme"); + p_sys->polarized = 0; enum scheme_e scheme = red_cyan; if (psz_scheme) { @@ -129,6 +134,8 @@ static int Create(vlc_object_t *p_this) scheme = trioscopic; else if (!strcmp(psz_scheme, "magenta-cyan")) scheme = magenta_cyan; + else if (!strcmp(psz_scheme, "polarized")) + scheme = polarized; else msg_Err(p_filter, "Unknown anaglyph color scheme '%s'", psz_scheme); } @@ -156,6 +163,9 @@ static int Create(vlc_object_t *p_this) p_sys->left = 0xff00ff; p_sys->right = 0x00ffff; break; + case polarized: + p_sys->polarized = 1; + break; case unknown: msg_Err(p_filter, "Oops"); break; @@ -191,8 +201,12 @@ static picture_t *Filter(filter_t *p_filter, picture_t *p_pic) case VLC_CODEC_I420: case VLC_CODEC_J420: case VLC_CODEC_YV12: - combine_side_by_side_yuv420(p_pic, p_outpic, - p_sys->left, p_sys->right); + if (p_sys->polarized) { + combine_side_by_side_yuv420_polarized(p_pic, p_outpic); + } else { + combine_side_by_side_yuv420(p_pic, p_outpic, + p_sys->left, p_sys->right); + } break; default: @@ -205,6 +219,68 @@ static picture_t *Filter(filter_t *p_filter, picture_t *p_pic) return CopyInfoAndRelease(p_outpic, p_pic); } +static int blend(int c1, int c2) { + return (int)sqrt((c1*c1 + c2*c2)/2); +} + +static void combine_side_by_side_yuv420_polarized(picture_t *p_inpic, + picture_t *p_outpic) +{ + uint8_t *y1inl = p_inpic->p[Y_PLANE].p_pixels; /*input line left*/ + uint8_t *uinl = p_inpic->p[U_PLANE].p_pixels; + uint8_t *vinl = p_inpic->p[V_PLANE].p_pixels; + + uint8_t *y1out = p_outpic->p[Y_PLANE].p_pixels; + uint8_t *uout = p_outpic->p[U_PLANE].p_pixels; + uint8_t *vout = p_outpic->p[V_PLANE].p_pixels; + + const int in_pitch = p_inpic->p[Y_PLANE].i_pitch; + const int out_pitch = p_outpic->p[Y_PLANE].i_pitch; + + const int visible_pitch = p_inpic->p[Y_PLANE].i_visible_pitch; + const int visible_lines = p_inpic->p[Y_PLANE].i_visible_lines; + /*const int uv_visible_pitch = p_inpic->p[U_PLANE].i_visible_pitch;*/ + + int cnt,col; + int uinc = p_inpic->p[U_PLANE].i_pitch; + int vinc = p_inpic->p[V_PLANE].i_pitch; + int uoutc = p_outpic->p[U_PLANE].i_pitch; + int voutc = p_outpic->p[V_PLANE].i_pitch; + for (cnt=0;cnt<visible_lines / 2;cnt++) { + for(col=0; col<visible_pitch;col++) { + int halfw = visible_pitch / 2; + int left_idx = col/2; + int right_idx = left_idx + halfw; + y1out[col] = blend(y1inl[left_idx], y1inl[left_idx + in_pitch]); + y1out[col + out_pitch] = blend(y1inl[right_idx], y1inl[right_idx + in_pitch]); + } + y1inl += in_pitch * 2; + y1out += out_pitch * 2; + } + + for (cnt=0;cnt<p_inpic->p[U_PLANE].i_visible_lines / 2;cnt++) { + for(col=0; col<uinc;col++) { + int halfw = uinc / 2; + int left_idx = col/2; + int right_idx = left_idx + halfw; + uout[col] = blend(uinl[left_idx], uinl[left_idx + uinc]); + uout[col + uoutc] = blend(uinl[right_idx], uinl[right_idx + uinc]); + } + + for(col=0; col<vinc;col++) { + int halfw = vinc / 2; + int left_idx = col/2; + int right_idx = left_idx + halfw; + vout[col] = blend(vinl[left_idx], vinl[left_idx + vinc]); + vout[col + voutc] = blend(vinl[right_idx], vinl[right_idx + vinc]); + } + + uinl += uinc * 2; + vinl += vinc * 2; + uout += uinc * 2; + vout += vinc * 2; + } +} static void combine_side_by_side_yuv420(picture_t *p_inpic, picture_t *p_outpic, int left, int right)