X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fvideo_output%2Fvideo_output.c;h=8d82a419a19c661b088f822143badbfa34a300fe;hb=dd50e81c8969905671c66dfe7a927ca41aa2ded7;hp=79c4ad37e0bea1355bb43163189b643fd86955d5;hpb=9f410e429acdeb12bc75ccc98ee0a325a7c07e37;p=vlc diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 79c4ad37e0..8d82a419a1 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -43,11 +43,10 @@ #include #include -#include +#include #include #include -#include "vout_pictures.h" #include "vout_internal.h" #include "interlacing.h" #include "postprocessing.h" @@ -162,11 +161,7 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout, free( psz_filter_chain ); } -#warning "FIXME: Check RGB masks in vout_Request" - /* FIXME: check RGB masks */ - if( p_vout->p->fmt_render.i_chroma != vlc_fourcc_GetCodec( VIDEO_ES, p_fmt->i_chroma ) || - p_vout->p->fmt_render.i_width != p_fmt->i_width || - p_vout->p->fmt_render.i_height != p_fmt->i_height || + if( !video_format_IsSimilar( &p_vout->p->original, p_fmt ) || p_vout->p->b_filter_change ) { vlc_mutex_unlock( &p_vout->p->change_lock ); @@ -179,32 +174,6 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout, else { /* This video output is cool! Hijack it. */ - /* Correct aspect ratio on change - * FIXME factorize this code with other aspect ration related code */ - unsigned int i_sar_num; - unsigned int i_sar_den; - vlc_ureduce( &i_sar_num, &i_sar_den, - p_fmt->i_sar_num, p_fmt->i_sar_den, 50000 ); -#if 0 - /* What's that, it does not seems to be used correcly everywhere */ - if( p_vout->i_par_num > 0 && p_vout->i_par_den > 0 ) - { - i_sar_num *= p_vout->i_par_den; - i_sar_den *= p_vout->i_par_num; - } -#endif - - if( i_sar_num > 0 && i_sar_den > 0 && - ( i_sar_num != p_vout->p->fmt_render.i_sar_num || - i_sar_den != p_vout->p->fmt_render.i_sar_den ) ) - { - p_vout->p->fmt_in.i_sar_num = i_sar_num; - p_vout->p->fmt_in.i_sar_den = i_sar_den; - - p_vout->p->fmt_render.i_sar_num = i_sar_num; - p_vout->p->fmt_render.i_sar_den = i_sar_den; - p_vout->p->i_changes |= VOUT_ASPECT_CHANGE; - } vlc_mutex_unlock( &p_vout->p->change_lock ); vlc_object_release( p_vout ); @@ -273,17 +242,12 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt ) } /* */ - p_vout->p->fmt_render = *p_fmt; /* FIXME palette */ - p_vout->p->fmt_in = *p_fmt; /* FIXME palette */ - - p_vout->p->fmt_render.i_chroma = - p_vout->p->fmt_in.i_chroma = i_chroma; - video_format_FixRgb( &p_vout->p->fmt_render ); - video_format_FixRgb( &p_vout->p->fmt_in ); + p_vout->p->original = *p_fmt; /* FIXME palette */ + p_vout->p->original.i_chroma = i_chroma; + video_format_FixRgb( &p_vout->p->original ); /* Initialize misc stuff */ vout_control_Init( &p_vout->p->control ); - p_vout->p->i_changes = 0; vout_chrono_Init( &p_vout->p->render, 5, 10000 ); /* Arbitrary initial time */ vout_statistic_Init( &p_vout->p->statistic ); p_vout->p->b_filter_change = 0; @@ -594,6 +558,42 @@ void vout_ControlChangeZoom(vout_thread_t *vout, int num, int den) vout_control_PushPair(&vout->p->control, VOUT_CONTROL_ZOOM, num, den); } +void vout_ControlChangeSampleAspectRatio(vout_thread_t *vout, + unsigned num, unsigned den) +{ + vout_control_PushPair(&vout->p->control, VOUT_CONTROL_ASPECT_RATIO, + num, den); +} +void vout_ControlChangeCropRatio(vout_thread_t *vout, + unsigned num, unsigned den) +{ + vout_control_PushPair(&vout->p->control, VOUT_CONTROL_CROP_RATIO, + num, den); +} +void vout_ControlChangeCropWindow(vout_thread_t *vout, + int x, int y, int width, int height) +{ + vout_control_cmd_t cmd; + vout_control_cmd_Init(&cmd, VOUT_CONTROL_CROP_WINDOW); + cmd.u.window.x = x; + cmd.u.window.y = y; + cmd.u.window.width = width; + cmd.u.window.height = height; + + vout_control_Push(&vout->p->control, &cmd); +} +void vout_ControlChangeCropBorder(vout_thread_t *vout, + int left, int top, int right, int bottom) +{ + vout_control_cmd_t cmd; + vout_control_cmd_Init(&cmd, VOUT_CONTROL_CROP_BORDER); + cmd.u.border.left = left; + cmd.u.border.top = top; + cmd.u.border.right = right; + cmd.u.border.bottom = bottom; + + vout_control_Push(&vout->p->control, &cmd); +} /***************************************************************************** * InitThread: initialize video output thread @@ -614,19 +614,14 @@ static int ThreadInit(vout_thread_t *vout) /* print some usefull debug info about different vout formats */ - PrintVideoFormat(vout, "pic render", &vout->p->fmt_render); - PrintVideoFormat(vout, "pic in", &vout->p->fmt_in); - PrintVideoFormat(vout, "pic out", &vout->p->fmt_out); - - assert(vout->p->fmt_out.i_width == vout->p->fmt_render.i_width && - vout->p->fmt_out.i_height == vout->p->fmt_render.i_height && - vout->p->fmt_out.i_chroma == vout->p->fmt_render.i_chroma); + PrintVideoFormat(vout, "pic render", &vout->p->original); return VLC_SUCCESS; } static int ThreadDisplayPicture(vout_thread_t *vout, bool now, mtime_t *deadline) { + vout_display_t *vd = vout->p->display.vd; int displayed_count = 0; int lost_count = 0; @@ -744,7 +739,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout, (vout->p->decoder_pool != vout->p->display_pool || subpic)) { picture_t *render; if (vout->p->is_decoder_pool_slow) - render = picture_NewFromFormat(&vout->p->fmt_out); + render = picture_NewFromFormat(&vd->source); else if (vout->p->decoder_pool != vout->p->display_pool) render = picture_pool_Get(vout->p->display_pool); else @@ -754,8 +749,8 @@ static int ThreadDisplayPicture(vout_thread_t *vout, picture_Copy(render, filtered); spu_RenderSubpictures(vout->p->p_spu, - render, &vout->p->fmt_out, - subpic, &vout->p->fmt_in, spu_render_time); + render, &vd->source, + subpic, &vd->source, spu_render_time); } if (vout->p->is_decoder_pool_slow) { direct = picture_pool_Get(vout->p->display_pool); @@ -776,7 +771,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout, * Take a snapshot if requested */ if (direct && do_snapshot) - vout_snapshot_Set(&vout->p->snapshot, &vout->p->fmt_out, direct); + vout_snapshot_Set(&vout->p->snapshot, &vd->source, direct); /* Render the direct buffer returned by vout_RenderPicture */ if (direct) { @@ -845,33 +840,21 @@ static int ThreadManage(vout_thread_t *vout, static void ThreadDisplayOsdTitle(vout_thread_t *vout, const char *string) { - if( !var_InheritBool(vout, "osd")) - return; if (!vout->p->title.show) return; vlc_assert_locked(&vout->p->change_lock); - const mtime_t start = mdate(); - const mtime_t stop = start + - INT64_C(1000) * vout->p->title.timeout; - - if (stop > start) - vout_ShowTextAbsolute(vout, SPU_DEFAULT_CHANNEL, - string, NULL, - vout->p->title.position, - 30 + vout->p->fmt_in.i_width - - vout->p->fmt_in.i_visible_width - - vout->p->fmt_in.i_x_offset, - 20 + vout->p->fmt_in.i_y_offset, - start, stop); + vout_OSDText(vout, SPU_DEFAULT_CHANNEL, + vout->p->title.position, INT64_C(1000) * vout->p->title.timeout, + string); } static void ThreadChangeFilters(vout_thread_t *vout, const char *filters) { es_format_t fmt; - es_format_Init(&fmt, VIDEO_ES, vout->p->fmt_render.i_chroma); - fmt.video = vout->p->fmt_render; + es_format_Init(&fmt, VIDEO_ES, vout->p->original.i_chroma); + fmt.video = vout->p->original; vlc_mutex_lock(&vout->p->vfilter_lock); @@ -988,6 +971,79 @@ static void ThreadChangeZoom(vout_thread_t *vout, int num, int den) vout_SetDisplayZoom(vout->p->display.vd, num, den); } +static void ThreadChangeAspectRatio(vout_thread_t *vout, + unsigned num, unsigned den) +{ + const video_format_t *source = &vout->p->original; + + if (num > 0 && den > 0) { + num *= source->i_visible_height; + den *= source->i_visible_width; + vlc_ureduce(&num, &den, num, den, 0); + } + vout_SetDisplayAspect(vout->p->display.vd, num, den); +} + + +static void ThreadExecuteCropWindow(vout_thread_t *vout, + unsigned crop_num, unsigned crop_den, + unsigned x, unsigned y, + unsigned width, unsigned height) +{ + const video_format_t *source = &vout->p->original; + + vout_SetDisplayCrop(vout->p->display.vd, + crop_num, crop_den, + source->i_x_offset + x, + source->i_y_offset + y, + width, height); +} +static void ThreadExecuteCropBorder(vout_thread_t *vout, + unsigned left, unsigned top, + unsigned right, unsigned bottom) +{ + const video_format_t *source = &vout->p->original; + ThreadExecuteCropWindow(vout, 0, 0, + left, + top, + /* At worst, it becomes < 0 (but unsigned) and will be rejected */ + source->i_visible_width - (left + right), + source->i_visible_height - (top + bottom)); +} + +static void ThreadExecuteCropRatio(vout_thread_t *vout, + unsigned num, unsigned den) +{ + const video_format_t *source = &vout->p->original; + + int x, y; + int width, height; + if (num <= 0 || den <= 0) { + num = 0; + den = 0; + x = 0; + y = 0; + width = source->i_visible_width; + height = source->i_visible_height; + } else { + unsigned scaled_width = (uint64_t)source->i_visible_height * num * source->i_sar_den / den / source->i_sar_num; + unsigned scaled_height = (uint64_t)source->i_visible_width * den * source->i_sar_num / num / source->i_sar_den; + + if (scaled_width < source->i_visible_width) { + x = (source->i_visible_width - scaled_width) / 2; + y = 0; + width = scaled_width; + height = source->i_visible_height; + } else { + x = 0; + y = (source->i_visible_height - scaled_height) / 2; + width = source->i_visible_width; + height = scaled_height; + } + } + ThreadExecuteCropWindow(vout, num, den, x, y, width, height); +} + static void ThreadClean(vout_thread_t *vout) { /* Destroy translation tables */ @@ -1083,6 +1139,22 @@ static void *Thread(void *object) case VOUT_CONTROL_ZOOM: ThreadChangeZoom(vout, cmd.u.pair.a, cmd.u.pair.b); break; + case VOUT_CONTROL_ASPECT_RATIO: + ThreadChangeAspectRatio(vout, cmd.u.pair.a, cmd.u.pair.b); + break; + case VOUT_CONTROL_CROP_RATIO: + ThreadExecuteCropRatio(vout, cmd.u.pair.a, cmd.u.pair.b); + break; + case VOUT_CONTROL_CROP_WINDOW: + ThreadExecuteCropWindow(vout, 0, 0, + cmd.u.window.x, cmd.u.window.y, + cmd.u.window.width, cmd.u.window.height); + break; + case VOUT_CONTROL_CROP_BORDER: + ThreadExecuteCropBorder(vout, + cmd.u.border.left, cmd.u.border.top, + cmd.u.border.right, cmd.u.border.bottom); + break; default: break; }