summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gtk/src/ghb.ui19
-rw-r--r--gtk/src/hb-backend.c254
-rw-r--r--gtk/src/hb-backend.h2
-rw-r--r--gtk/src/internal_defaults.xml2
-rw-r--r--gtk/src/preview.c7
-rw-r--r--libhb/hb.c39
6 files changed, 183 insertions, 140 deletions
diff --git a/gtk/src/ghb.ui b/gtk/src/ghb.ui
index 489ebbb16..8d52e299b 100644
--- a/gtk/src/ghb.ui
+++ b/gtk/src/ghb.ui
@@ -5302,16 +5302,29 @@ the required multiple.</property>
</packing>
</child>
<child>
+ <object class="GtkCheckButton" id="show_crop">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip-text" translatable="yes">Show Cropped area of the preview</property>
+ <property name="label" translatable="yes">Show Crop</property>
+ <signal name="toggled" handler="scale_changed_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkToggleButton" id="preview_fullscreen">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip-text" translatable="yes">View Fullscreen Preview</property>
<property name="label" translatable="yes">Fullscreen</property>
- <signal handler="fullscreen_clicked_cb" name="clicked"/>
+ <signal handler="fullscreen_clicked_cb" name="toggled"/>
</object>
<packing>
<property name="expand">False</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
@@ -5324,7 +5337,7 @@ the required multiple.</property>
</object>
<packing>
<property name="expand">False</property>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
</object>
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index 3a327343e..80d85bee8 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -922,25 +922,6 @@ get_acodec_value(gint val)
return value;
}
-#if 0
-static GValue*
-get_abitrate_value(gint val)
-{
- GValue *value = NULL;
- gint ii;
-
- for (ii = 0; ii < hb_audio_bitrates_count; ii++)
- {
- if (hb_audio_bitrates[ii].rate == val)
- {
- value = ghb_string_value_new(hb_audio_bitrates[ii].string);
- break;
- }
- }
- return value;
-}
-#endif
-
static GValue*
get_amix_value(gint val)
{
@@ -2769,16 +2750,6 @@ ghb_set_scale(signal_user_data_t *ud, gint mode)
max_height = MOD_DOWN(
ghb_settings_get_int(ud->settings, "PictureHeight"), mod);
}
- // Adjust dims according to max values
- if (!max_height)
- {
- max_height = MOD_DOWN(crop_height, mod);
- }
- if (!max_width)
- {
- max_width = MOD_DOWN(crop_width, mod);
- }
- // Align max dims
g_debug("max_width %d, max_height %d\n", max_width, max_height);
if (width < 16)
@@ -2788,6 +2759,8 @@ ghb_set_scale(signal_user_data_t *ud, gint mode)
width = MOD_ROUND(width, mod);
height = MOD_ROUND(height, mod);
+
+ // Adjust dims according to max values
if (max_height)
height = MIN(height, max_height);
if (max_width)
@@ -2936,6 +2909,21 @@ set_preview_job_settings(hb_job_t *job, GValue *settings)
ghb_settings_combo_int(settings, "PictureModulus");
job->width = ghb_settings_get_int(settings, "scale_width");
job->height = ghb_settings_get_int(settings, "scale_height");
+ if (ghb_settings_get_boolean(settings, "show_crop"))
+ {
+ gint c0, c1;
+
+ c0 = MAX(job->crop[0] - 32, 0);
+ c1 = MAX(job->crop[1] - 32, 0);
+ job->height += (job->crop[0] - c0) + (job->crop[1] - c1);
+ job->crop[0] = c0;
+ job->crop[1] = c1;
+ c0 = MAX(job->crop[2] - 32, 0);
+ c1 = MAX(job->crop[3] - 32, 0);
+ job->width += (job->crop[2] - c0) + (job->crop[3] - c1);
+ job->crop[2] = c0;
+ job->crop[3] = c1;
+ }
gint deint = ghb_settings_combo_int(settings, "PictureDeinterlace");
gint decomb = ghb_settings_combo_int(settings, "PictureDecomb");
@@ -3918,15 +3906,101 @@ ghb_pause_queue()
}
}
-#define RED_HEIGHT 720.0
-#define RED_WIDTH 1280.0
+static void
+vert_line(
+ GdkPixbuf * pb,
+ guint8 r,
+ guint8 g,
+ guint8 b,
+ gint x,
+ gint y,
+ gint len,
+ gint width)
+{
+ guint8 *pixels = gdk_pixbuf_get_pixels (pb);
+ guint8 *dst;
+ gint ii, jj;
+ gint channels = gdk_pixbuf_get_n_channels (pb);
+ gint stride = gdk_pixbuf_get_rowstride (pb);
+
+ for (jj = 0; jj < width; jj++)
+ {
+ dst = pixels + y * stride + (x+jj) * channels;
+ for (ii = 0; ii < len; ii++)
+ {
+ dst[0] = r;
+ dst[1] = g;
+ dst[2] = b;
+ dst += stride;
+ }
+ }
+}
+
+static void
+horz_line(
+ GdkPixbuf * pb,
+ guint8 r,
+ guint8 g,
+ guint8 b,
+ gint x,
+ gint y,
+ gint len,
+ gint width)
+{
+ guint8 *pixels = gdk_pixbuf_get_pixels (pb);
+ guint8 *dst;
+ gint ii, jj;
+ gint channels = gdk_pixbuf_get_n_channels (pb);
+ gint stride = gdk_pixbuf_get_rowstride (pb);
+
+ for (jj = 0; jj < width; jj++)
+ {
+ dst = pixels + (y+jj) * stride + x * channels;
+ for (ii = 0; ii < len; ii++)
+ {
+ dst[0] = r;
+ dst[1] = g;
+ dst[2] = b;
+ dst += channels;
+ }
+ }
+}
+
+static void
+hash_pixbuf(
+ GdkPixbuf * pb,
+ gint x,
+ gint y,
+ gint w,
+ gint h,
+ gint step,
+ gint orientation)
+{
+ gint ii;
+
+ if (!orientation)
+ {
+ // vertical lines
+ for (ii = x; ii < x+w; ii += step)
+ {
+ vert_line(pb, 0x80, 0x80, 0x80, ii, y, h, 4);
+ }
+ }
+ else
+ {
+ // horizontal lines
+ for (ii = y; ii < y+h; ii += step)
+ {
+ horz_line(pb, 0x80, 0x80, 0x80, x, ii, w, 4);
+ }
+ }
+}
GdkPixbuf*
ghb_get_preview_image(
gint titleindex,
gint index,
signal_user_data_t *ud,
- gboolean borders,
gint *out_width,
gint *out_height)
{
@@ -3946,14 +4020,6 @@ ghb_get_preview_image(
if (title->job == NULL) return NULL;
set_preview_job_settings(title->job, settings);
- // hb_get_preview can't handle sizes that are larger than the original title
- // dimensions
- if (title->job->width > title->width)
- title->job->width = title->width;
-
- if (title->job->height > title->height)
- title->job->height = title->height;
-
// hb_get_preview doesn't compensate for anamorphic, so lets
// calculate scale factors
gint width, height, par_width = 1, par_height = 1;
@@ -3964,63 +4030,15 @@ ghb_get_preview_image(
&par_width, &par_height );
}
- // And also creates artifacts if the width is not a multiple of 8
- //title->job->width = ((title->job->width + 4) >> 3) << 3;
- // And the height must be a multiple of 2
- //title->job->height = ((title->job->height + 1) >> 1) << 1;
-
- // Make sure we have a big enough buffer to receive the image from libhb. libhb
- // creates images with a one-pixel border around the original content. Hence we
- // add 2 pixels horizontally and vertically to the buffer size.
- gint srcWidth = title->width + 2;
- gint srcHeight= title->height + 2;
- gint dstWidth = title->width;
- gint dstHeight= title->height;
- gint borderTop = 1;
- gint borderLeft = 1;
- if (borders)
- {
- // |<---------- title->width ----------->|
- // | |<---- title->job->width ---->| |
- // | | | |
- // .......................................
- // ....+-----------------------------+....
- // ....| |....<-- gray border
- // ....| |....
- // ....| |....
- // ....| |<------- image
- // ....| |....
- // ....| |....
- // ....| |....
- // ....| |....
- // ....| |....
- // ....+-----------------------------+....
- // .......................................
- dstWidth = title->job->width;
- dstHeight = title->job->height;
- borderTop = (srcHeight - dstHeight) / 2;
- borderLeft = (srcWidth - dstWidth) / 2;
- g_debug("boarders removed\n");
- }
-
- g_debug("src %d x %d\n", srcWidth, srcHeight);
- g_debug("dst %d x %d\n", dstWidth, dstHeight);
- g_debug("job dim %d x %d\n", title->job->width, title->job->height);
- g_debug("title crop %d:%d:%d:%d\n",
- title->crop[0],
- title->crop[1],
- title->crop[2],
- title->crop[3]);
- g_debug("job crop %d:%d:%d:%d\n",
- title->job->crop[0],
- title->job->crop[1],
- title->job->crop[2],
- title->job->crop[3]);
+ // Make sure we have a big enough buffer to receive the image from libhb
+ gint dstWidth = title->job->width;
+ gint dstHeight= title->job->height;
+
static guint8 *buffer = NULL;
static gint bufferSize = 0;
-
gint newSize;
- newSize = srcWidth * srcHeight * 4;
+
+ newSize = dstWidth * dstHeight * 4;
if( bufferSize < newSize )
{
bufferSize = newSize;
@@ -4029,23 +4047,22 @@ ghb_get_preview_image(
hb_get_preview( h_scan, title, index, buffer );
// Create an GdkPixbuf and copy the libhb image into it, converting it from
- // libhb's format something suitable. Along the way, we'll strip off the
- // border around libhb's image.
+ // libhb's format something suitable.
- // The image data returned by hb_get_preview is 4 bytes per pixel, BGRA format.
- // Alpha is ignored.
+ // The image data returned by hb_get_preview is 4 bytes per pixel,
+ // BGRA format. Alpha is ignored.
GdkPixbuf *preview = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, dstWidth, dstHeight);
guint8 *pixels = gdk_pixbuf_get_pixels (preview);
guint32 *src = (guint32*)buffer;
guint8 *dst = pixels;
- src += borderTop * srcWidth; // skip top rows in src to get to first row of dst
- src += borderLeft; // skip left pixels in src to get to first pixel of dst
+
gint ii, jj;
gint channels = gdk_pixbuf_get_n_channels (preview);
gint stride = gdk_pixbuf_get_rowstride (preview);
guint8 *tmp;
+
for (ii = 0; ii < dstHeight; ii++)
{
tmp = dst;
@@ -4058,11 +4075,23 @@ ghb_get_preview_image(
src++;
}
dst += stride;
- src += (srcWidth - dstWidth); // skip to next row in src
}
+ gint w = ghb_settings_get_int(settings, "scale_width");
+ gint h = ghb_settings_get_int(settings, "scale_height");
+ ghb_par_scale(ud, &w, &h, par_width, par_height);
+
+ gint c0, c1, c2, c3;
+ c0 = ghb_settings_get_int(settings, "PictureTopCrop");
+ c1 = ghb_settings_get_int(settings, "PictureBottomCrop");
+ c2 = ghb_settings_get_int(settings, "PictureLeftCrop");
+ c3 = ghb_settings_get_int(settings, "PictureRightCrop");
+
+ gdouble xscale = (gdouble)w / (gdouble)(title->width - c2 - c3);
+ gdouble yscale = (gdouble)h / (gdouble)(title->height - c0 - c1);
+
ghb_par_scale(ud, &dstWidth, &dstHeight, par_width, par_height);
- *out_width = dstWidth;
- *out_height = dstHeight;
+ *out_width = w;
+ *out_height = h;
if (ghb_settings_get_boolean(settings, "reduce_hd_preview"))
{
GdkScreen *ss;
@@ -4090,10 +4119,27 @@ ghb_get_preview_image(
dstHeight = s_h * factor / 100;
dstWidth = dstWidth * dstHeight / orig_h;
}
+ xscale *= dstWidth / orig_w;
+ yscale *= dstHeight / orig_h;
}
- g_debug("scaled %d x %d\n", dstWidth, dstHeight);
+ g_debug("scaled %d x %d", dstWidth, dstHeight);
GdkPixbuf *scaled_preview;
scaled_preview = gdk_pixbuf_scale_simple(preview, dstWidth, dstHeight, GDK_INTERP_HYPER);
+ if (ghb_settings_get_boolean(settings, "show_crop"))
+ {
+ c0 = (32 + MIN(c0 - 32, 0)) * yscale;
+ c1 = (32 + MIN(c1 - 32, 0)) * yscale;
+ c2 = (32 + MIN(c2 - 32, 0)) * xscale;
+ c3 = (32 + MIN(c3 - 32, 0)) * xscale;
+ // Top
+ hash_pixbuf(scaled_preview, c2, 0, w, c0, 16, 0);
+ // Bottom
+ hash_pixbuf(scaled_preview, c2, dstHeight-c1, w, c1, 16, 0);
+ // Left
+ hash_pixbuf(scaled_preview, 0, c0, c2, h, 16, 1);
+ // Right
+ hash_pixbuf(scaled_preview, dstWidth-c3, c0, c3, h, 16, 1);
+ }
g_object_unref (preview);
return scaled_preview;
}
diff --git a/gtk/src/hb-backend.h b/gtk/src/hb-backend.h
index 2b27d532a..d946b9224 100644
--- a/gtk/src/hb-backend.h
+++ b/gtk/src/hb-backend.h
@@ -144,7 +144,7 @@ gint ghb_longest_title(void);
gchar* ghb_build_x264opts_string(GValue *settings);
GdkPixbuf* ghb_get_preview_image(
gint titleindex, gint index, signal_user_data_t *ud,
- gboolean borders, gint *width, gint *height);
+ 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/internal_defaults.xml b/gtk/src/internal_defaults.xml
index f2bc8d336..eb858d019 100644
--- a/gtk/src/internal_defaults.xml
+++ b/gtk/src/internal_defaults.xml
@@ -38,6 +38,8 @@
<integer>0</integer>
<key>scale_width</key>
<integer>0</integer>
+ <key>show_crop</key>
+ <false />
<key>single_title</key>
<integer>1</integer>
<key>start_chapter</key>
diff --git a/gtk/src/preview.c b/gtk/src/preview.c
index ef5f8c738..5ec067b62 100644
--- a/gtk/src/preview.c
+++ b/gtk/src/preview.c
@@ -122,7 +122,10 @@ ghb_par_scale(signal_user_data_t *ud, gint *width, gint *height, gint par_n, gin
num = par_n * disp_par_d;
den = par_d * disp_par_n;
- *width = *width * num / den;
+ if (par_n > par_d)
+ *width = *width * num / den;
+ else
+ *height = *height * den / num;
}
void
@@ -667,7 +670,7 @@ ghb_set_preview_image(signal_user_data_t *ud)
ud->preview->pix =
ghb_get_preview_image(titleindex, ud->preview->frame,
- ud, TRUE, &width, &height);
+ ud, &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);
diff --git a/libhb/hb.c b/libhb/hb.c
index 943e2389f..2ffa16976 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -384,7 +384,7 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
char filename[1024];
FILE * file;
uint8_t * buf1, * buf2, * buf3, * buf4, * pen;
- uint32_t * p32, swsflags;
+ uint32_t swsflags;
AVPicture pic_in, pic_preview, pic_deint, pic_crop, pic_scale;
struct SwsContext * context;
int i;
@@ -395,14 +395,14 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
buf1 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height ) );
buf2 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height ) );
- buf3 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, job->width, job->height ) );
+ buf3 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, rgb_width, job->height ) );
buf4 = av_malloc( avpicture_get_size( PIX_FMT_RGBA32, rgb_width, job->height ) );
avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P,
title->width, title->height );
avpicture_fill( &pic_deint, buf2, PIX_FMT_YUV420P,
title->width, title->height );
avpicture_fill( &pic_scale, buf3, PIX_FMT_YUV420P,
- job->width, job->height );
+ rgb_width, job->height );
avpicture_fill( &pic_preview, buf4, PIX_FMT_RGBA32,
rgb_width, job->height );
@@ -439,7 +439,7 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
context = sws_getContext(title->width - (job->crop[2] + job->crop[3]),
title->height - (job->crop[0] + job->crop[1]),
PIX_FMT_YUV420P,
- job->width, job->height, PIX_FMT_YUV420P,
+ rgb_width, job->height, PIX_FMT_YUV420P,
swsflags, NULL, NULL, NULL);
// Scale
@@ -465,33 +465,12 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
// Free context
sws_freeContext( context );
- if( job->height < title->height || job->width < title->width )
+ preview_size = pic_preview.linesize[0];
+ pen = buffer;
+ for( i = 0; i < job->height; i++ )
{
- /* Gray background */
- p32 = (uint32_t *) buffer;
- for( i = 0; i < ( title->width + 2 ) * ( title->height + 2 ); i++ )
- {
- p32[i] = 0xFF808080;
- }
-
- /* Draw the picture, centered, and draw the cropping zone */
- preview_size = pic_preview.linesize[0];
- pen = buffer + ( title->height - job->height ) *
- ( title->width + 2 ) * 2 + ( title->width - job->width ) * 2;
- memset( pen, 0xFF, 4 * ( job->width + 2 ) );
- pen += 4 * ( title->width + 2 );
- for( i = 0; i < job->height; i++ )
- {
- uint8_t * nextLine;
- nextLine = pen + 4 * ( title->width + 2 );
- memset( pen, 0xFF, 4 );
- pen += 4;
- memcpy( pen, buf4 + preview_size * i, 4 * job->width );
- pen += 4 * job->width;
- memset( pen, 0xFF, 4 );
- pen = nextLine;
- }
- memset( pen, 0xFF, 4 * ( job->width + 2 ) );
+ memcpy( pen, buf4 + preview_size * i, 4 * job->width );
+ pen += 4 * job->width;
}
// Clean up