From c6fc88888ef58b2063594659f3e08c1251ea776a Mon Sep 17 00:00:00 2001 From: jstebbins Date: Fri, 5 Dec 2008 00:11:09 +0000 Subject: LinGui: make preview scalling take screen PAR into account git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2007 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- gtk/src/hb-backend.c | 43 ++++++++++++------ gtk/src/hb-backend.h | 3 +- gtk/src/presets.c | 2 +- gtk/src/preview.c | 124 +++++++++++++++++++++++++++++++++++---------------- gtk/src/preview.h | 1 + 5 files changed, 118 insertions(+), 55 deletions(-) (limited to 'gtk') diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c index 0b93a4d12..dc11f580b 100644 --- a/gtk/src/hb-backend.c +++ b/gtk/src/hb-backend.c @@ -31,6 +31,7 @@ #include "hb-backend.h" #include "settings.h" #include "callbacks.h" +#include "preview.h" #include "values.h" #include "lang.h" @@ -3535,12 +3536,16 @@ GdkPixbuf* ghb_get_preview_image( gint titleindex, gint index, - GValue *settings, - gboolean borders) + signal_user_data_t *ud, + gboolean borders, + gint *out_width, + gint *out_height) { + GValue *settings; hb_title_t *title; hb_list_t *list; + settings = ud->settings; list = hb_get_titles( h_scan ); if( !hb_list_count( list ) ) { @@ -3662,27 +3667,37 @@ ghb_get_preview_image( if (anamorphic) { hb_set_anamorphic_size( title->job, &width, &height, &par_width, &par_height ); - if (par_width > par_height) - dstWidth = dstWidth * par_width / par_height; - else - dstHeight = dstHeight * par_height / par_width; + ghb_par_scale(ud, &dstWidth, &dstHeight, par_width, par_height); + } + else + { + ghb_par_scale(ud, &dstWidth, &dstHeight, 1, 1); } + *out_width = dstWidth; + *out_height = dstHeight; if (ghb_settings_get_boolean(settings, "reduce_hd_preview")) { - gdouble factor = 1.0; + GdkScreen *ss; + gint s_w, s_h; + gint num, den; + + ss = gdk_screen_get_default(); + s_w = gdk_screen_get_width(ss); + s_h = gdk_screen_get_height(ss); + num = dstWidth * par_width; + den = dstHeight * par_height; - if (dstHeight > RED_HEIGHT) + if (dstWidth > s_w * 80 / 100) { - factor = RED_HEIGHT / (gdouble)dstHeight; + dstWidth = s_w * 80 / 100; + dstHeight = dstWidth * den / num; } - if (dstWidth * factor > RED_WIDTH) + if (dstHeight > s_h * 80 / 100) { - factor = RED_WIDTH / (gdouble)dstWidth; + dstHeight = s_h * 80 / 100; + dstWidth = dstHeight * num / den; } - dstHeight = dstHeight * factor + 0.5; - dstWidth = dstWidth * factor + 0.5; } - g_debug("scaled %d x %d\n", dstWidth, dstHeight); GdkPixbuf *scaled_preview; scaled_preview = gdk_pixbuf_scale_simple(preview, dstWidth, dstHeight, GDK_INTERP_HYPER); diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h index ff8609661..057bea693 100644 --- a/gtk/src/hb-backend.h +++ b/gtk/src/hb-backend.h @@ -134,7 +134,8 @@ gint ghb_find_audio_track(gint titleindex, const gchar *lang, gint index); gint ghb_longest_title(void); gchar* ghb_build_x264opts_string(GValue *settings); GdkPixbuf* ghb_get_preview_image( - gint titleindex, gint index, GValue *settings, gboolean borders); + gint titleindex, gint index, signal_user_data_t *ud, + gboolean borders, gint *width, gint *height); gint ghb_calculate_target_bitrate(GValue *settings, gint titleindex); gchar* ghb_dvd_volname(const gchar *device); gint ghb_get_title_number(gint titleindex); diff --git a/gtk/src/presets.c b/gtk/src/presets.c index 4153e38e4..8f38f7ea1 100644 --- a/gtk/src/presets.c +++ b/gtk/src/presets.c @@ -555,7 +555,7 @@ presets_find_default2(GValue *presets, gint *len) { if (preset_is_default(dict)) { - indices = malloc(MAX_NESTED_PRESET * sizeof(gint)); + indices = g_malloc(MAX_NESTED_PRESET * sizeof(gint)); indices[*len] = ii; (*len)++; return indices; diff --git a/gtk/src/preview.c b/gtk/src/preview.c index 20de012c0..5bc416f70 100644 --- a/gtk/src/preview.c +++ b/gtk/src/preview.c @@ -59,6 +59,54 @@ static GstBusSyncReply create_window(GstBus *bus, GstMessage *msg, gboolean preview_expose_cb(GtkWidget *widget, GdkEventExpose *event, signal_user_data_t *ud); +void +ghb_screen_par(signal_user_data_t *ud, gint *par_n, gint *par_d) +{ + GValue disp_par = {0,}; + GstElement *xover; + GObjectClass *klass; + GParamSpec *pspec; + + g_value_init(&disp_par, GST_TYPE_FRACTION); + gst_value_set_fraction(&disp_par, 1, 1); + g_object_get(ud->preview->play, "video-sink", &xover, NULL); + klass = G_OBJECT_GET_CLASS(xover); + pspec = g_object_class_find_property(klass, "pixel-aspect_ratio"); + if (pspec) + { + GValue par_prop = {0,}; + + g_value_init(&par_prop, pspec->value_type); + g_object_get_property(G_OBJECT(xover), "pixel-aspect-ratio", + &par_prop); + if (!g_value_transform(&par_prop, &disp_par)) + { + g_warning("transform failed"); + gst_value_set_fraction(&disp_par, 1, 1); + } + g_value_unset(&par_prop); + } + *par_n = gst_value_get_fraction_numerator(&disp_par); + *par_d = gst_value_get_fraction_denominator(&disp_par); + g_value_unset(&disp_par); +} + +void +ghb_par_scale(signal_user_data_t *ud, gint *width, gint *height, gint par_n, gint par_d) +{ + gint disp_par_n, disp_par_d; + gint64 num, den; + + ghb_screen_par(ud, &disp_par_n, &disp_par_d); + num = par_n * disp_par_d; + den = par_d * disp_par_n; + + if (num > den) + *width = *width * num / den; + else + *height = *height * den / num; +} + void ghb_preview_init(signal_user_data_t *ud) { @@ -166,7 +214,7 @@ get_stream_info_objects_for_type (GstElement *play, const gchar *typestr) } static void -caps_set(GstCaps *caps, preview_t *preview) +caps_set(GstCaps *caps, signal_user_data_t *ud) { GstStructure *ss; @@ -175,12 +223,8 @@ caps_set(GstCaps *caps, preview_t *preview) { gint fps_n, fps_d, width, height; guint num, den, par_n, par_d; - guint disp_par_n, disp_par_d; + gint disp_par_n, disp_par_d; const GValue *par; - GValue disp_par = {0,}; - GstElement *xover; - GObjectClass *klass; - GParamSpec *pspec; gst_structure_get_fraction(ss, "framerate", &fps_n, &fps_d); gst_structure_get_int(ss, "width", &width); @@ -189,28 +233,7 @@ caps_set(GstCaps *caps, preview_t *preview) par_n = gst_value_get_fraction_numerator(par); par_d = gst_value_get_fraction_denominator(par); - g_value_init(&disp_par, GST_TYPE_FRACTION); - gst_value_set_fraction(&disp_par, 1, 1); - g_object_get(preview->play, "video-sink", &xover, NULL); - klass = G_OBJECT_GET_CLASS(xover); - pspec = g_object_class_find_property(klass, "pixel-aspect_ratio"); - if (pspec) - { - GValue par_prop = {0,}; - - g_value_init(&par_prop, pspec->value_type); - g_object_get_property(G_OBJECT(xover), "pixel-aspect-ratio", - &par_prop); - if (!g_value_transform(&par_prop, &disp_par)) - { - g_warning("transform failed"); - gst_value_set_fraction(&disp_par, 1, 1); - } - g_value_unset(&par_prop); - } - disp_par_n = gst_value_get_fraction_numerator(&disp_par); - disp_par_d = gst_value_get_fraction_denominator(&disp_par); - g_value_unset(&disp_par); + ghb_screen_par(ud, &disp_par_n, &disp_par_d); gst_video_calculate_display_ratio( &num, &den, width, height, par_n, par_d, disp_par_n, disp_par_d); @@ -218,23 +241,44 @@ caps_set(GstCaps *caps, preview_t *preview) width = gst_util_uint64_scale_int(height, num, den); else height = gst_util_uint64_scale_int(width, den, num); + + if (ghb_settings_get_boolean(ud->settings, "reduce_hd_preview")) + { + GdkScreen *ss; + gint s_w, s_h; + + ss = gdk_screen_get_default(); + s_w = gdk_screen_get_width(ss); + s_h = gdk_screen_get_height(ss); + + if (width > s_w * 80 / 100) + { + width = s_w * 80 / 100; + height = gst_util_uint64_scale_int(width, den, num); + } + if (height > s_h * 80 / 100) + { + height = s_h * 80 / 100; + width = gst_util_uint64_scale_int(height, num, den); + } + } - if (width != preview->width || height != preview->height) + if (width != ud->preview->width || height != ud->preview->height) { - gtk_widget_set_size_request(preview->view, width, height); - preview->width = width; - preview->height = height; + gtk_widget_set_size_request(ud->preview->view, width, height); + ud->preview->width = width; + ud->preview->height = height; } } } static void -update_stream_info(preview_t *preview) +update_stream_info(signal_user_data_t *ud) { GList *vstreams, *ll; GstPad *vpad = NULL; - vstreams = get_stream_info_objects_for_type(preview->play, "video"); + vstreams = get_stream_info_objects_for_type(ud->preview->play, "video"); if (vstreams) { for (ll = vstreams; vpad == NULL && ll != NULL; ll = ll->next) @@ -249,7 +293,7 @@ update_stream_info(preview_t *preview) caps = gst_pad_get_negotiated_caps(vpad); if (caps) { - caps_set(caps, preview); + caps_set(caps, ud); gst_caps_unref(caps); } //g_signal_connect(vpad, "notify::caps", G_CALLBACK(caps_set_cb), preview); @@ -300,7 +344,7 @@ live_preview_cb(GstBus *bus, GstMessage *msg, gpointer data) gst_element_get_state(ud->preview->play, &state, &pending, 0); if (state == GST_STATE_PAUSED || state == GST_STATE_PLAYING) { - update_stream_info(ud->preview); + update_stream_info(ud); } } break; @@ -568,8 +612,10 @@ ghb_set_preview_image(signal_user_data_t *ud) } if (ud->preview->pix != NULL) g_object_unref(ud->preview->pix); - ud->preview->pix = ghb_get_preview_image(titleindex, ud->preview->frame, - ud->settings, TRUE); + + ud->preview->pix = + ghb_get_preview_image(titleindex, ud->preview->frame, + ud, TRUE, &width, &height); if (ud->preview->pix == NULL) return; preview_width = gdk_pixbuf_get_width(ud->preview->pix); preview_height = gdk_pixbuf_get_height(ud->preview->pix); @@ -585,7 +631,7 @@ ghb_set_preview_image(signal_user_data_t *ud) widget->window, NULL, ud->preview->pix, 0, 0, 0, 0, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); - gchar *text = g_strdup_printf("%d x %d", preview_width, preview_height); + gchar *text = g_strdup_printf("%d x %d", width, height); widget = GHB_WIDGET (ud->builder, "preview_dims"); gtk_label_set_text(GTK_LABEL(widget), text); g_free(text); diff --git a/gtk/src/preview.h b/gtk/src/preview.h index 2b026fed0..1cc6ecf0b 100644 --- a/gtk/src/preview.h +++ b/gtk/src/preview.h @@ -22,5 +22,6 @@ void ghb_live_preview_progress(signal_user_data_t *ud); void ghb_live_encode_done(signal_user_data_t *ud, gboolean success); void ghb_preview_cleanup(signal_user_data_t *ud); void ghb_live_reset(signal_user_data_t *ud); +void ghb_par_scale(signal_user_data_t *ud, gint *width, gint *height, gint par_n, gint par_d); #endif // _GHB_PREVIEW_H_ -- cgit v1.2.3