summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2014-07-29 18:40:38 +0000
committerjstebbins <[email protected]>2014-07-29 18:40:38 +0000
commit6942656aeac26e63e87d8c1772ccec3e64b437e1 (patch)
treee82d337589c6bcfafe17963337f99ad6d41ec890
parent56680a9b967772ca6eb9112ac6f2a9e9bbe7244b (diff)
libhb: add new function for retrieving previews
This new function has a couple advantages over the old one (which we should phase out). It does not require hb_job_t as a parameter, instead it uses hb_ui_geometry_t which is a smaller and simpler struct. The entire job struct is overkill as input to this function. It returns an hb_image_t that fully describes the returned image instead of just a uint8_t array. The caller does not have to make assumptions about image size, line stide, or pixel format since hb_image_t specifies these things. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6242 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--gtk/src/hb-backend.c29
-rw-r--r--libhb/common.c16
-rw-r--r--libhb/common.h21
-rw-r--r--libhb/fifo.c52
-rw-r--r--libhb/hb.c122
-rw-r--r--libhb/hb.h12
-rw-r--r--libhb/internal.h3
7 files changed, 200 insertions, 55 deletions
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index dc6359445..175d523cc 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -5046,18 +5046,8 @@ ghb_get_preview_image(
uiGeo.par.num = 1;
uiGeo.par.den = 1;
- // Populate job with things needed by hb_get_preview
- hb_job_t *job = hb_job_init((hb_title_t*)title);
- job->width = uiGeo.width;
- job->height = uiGeo.height;
- job->deinterlace = deinterlace;
- memcpy(job->crop, uiGeo.crop, sizeof(int[4]));
-
- // Make sure we have a big enough buffer to receive the image from libhb
- guint8 *buffer = g_malloc(uiGeo.width * uiGeo.height * 4);
-
- hb_get_preview( h_scan, job, index, buffer );
- hb_job_close( &job );
+ hb_image_t *image;
+ image = hb_get_preview2(h_scan, title->index, index, &uiGeo, deinterlace);
// Create an GdkPixbuf and copy the libhb image into it, converting it from
// libhb's format something suitable.
@@ -5065,10 +5055,10 @@ ghb_get_preview_image(
// BGRA format. Alpha is ignored.
GdkPixbuf *preview;
preview = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
- uiGeo.width, uiGeo.height);
+ image->width, image->height);
guint8 *pixels = gdk_pixbuf_get_pixels(preview);
- guint8 *src_line = buffer;
+ guint8 *src_line = image->data;
guint8 *dst = pixels;
gint ii, jj;
@@ -5076,11 +5066,11 @@ ghb_get_preview_image(
gint stride = gdk_pixbuf_get_rowstride(preview);
guint8 *tmp;
- for (ii = 0; ii < uiGeo.height; ii++)
+ for (ii = 0; ii < image->height; ii++)
{
guint32 *src = (guint32*)src_line;
tmp = dst;
- for (jj = 0; jj < uiGeo.width; jj++)
+ for (jj = 0; jj < image->width; jj++)
{
tmp[0] = src[0] >> 16;
tmp[1] = src[0] >> 8;
@@ -5088,7 +5078,7 @@ ghb_get_preview_image(
tmp += channels;
src++;
}
- src_line += uiGeo.width * 4;
+ src_line += image->plane[0].stride;
dst += stride;
}
gint w = ghb_settings_get_int(ud->settings, "scale_width");
@@ -5107,8 +5097,8 @@ ghb_get_preview_image(
*out_width = w;
*out_height = h;
- int previewWidth = uiGeo.width;
- int previewHeight = uiGeo.height;
+ int previewWidth = image->width;
+ int previewHeight = image->height;
// If the preview is too large to fit the screen, reduce it's size.
if (ghb_settings_get_boolean(ud->prefs, "reduce_hd_preview"))
@@ -5167,6 +5157,7 @@ ghb_get_preview_image(
// Right
hash_pixbuf(preview, previewWidth-c3, c0, c3, h, 32, 1);
}
+ hb_image_close(&image);
return preview;
}
diff --git a/libhb/common.c b/libhb/common.c
index 0bb2eafd5..7c4a97eca 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -3119,6 +3119,22 @@ static void job_clean( hb_job_t * job )
}
}
+hb_title_t * hb_find_title_by_index( hb_handle_t *h, int title_index )
+{
+ hb_title_set_t *title_set = hb_get_title_set( h );
+ int ii;
+
+ for (ii = 0; ii < hb_list_count(title_set->list_title); ii++)
+ {
+ hb_title_t *title = hb_list_item(title_set->list_title, ii);
+ if (title_index == title->index)
+ {
+ return title;
+ }
+ }
+ return NULL;
+}
+
/*
* Create a pristine job structure from a title
* title_index is 1 based
diff --git a/libhb/common.h b/libhb/common.h
index c3bbc2c21..2882bdf37 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -81,6 +81,7 @@ typedef struct hb_container_s hb_container_t;
typedef struct hb_rational_s hb_rational_t;
typedef struct hb_geometry_s hb_geometry_t;
typedef struct hb_ui_geometry_s hb_ui_geometry_t;
+typedef struct hb_image_s hb_image_t;
typedef struct hb_job_s hb_job_t;
typedef struct hb_title_set_s hb_title_set_t;
typedef struct hb_title_s hb_title_t;
@@ -263,6 +264,26 @@ struct hb_ui_geometry_s
hb_rational_t dar; // Display aspect used in custom anamorphic
};
+struct hb_image_s
+{
+ int format;
+ int width;
+ int height;
+ uint8_t *data;
+
+ struct image_plane
+ {
+ uint8_t *data;
+ int width;
+ int height;
+ int stride;
+ int height_stride;
+ int size;
+ } plane[4];
+};
+
+void hb_image_close(hb_image_t **_image);
+
// Update win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_subtitle_config_s.cs when changing this struct
struct hb_subtitle_config_s
{
diff --git a/libhb/fifo.c b/libhb/fifo.c
index 043790e17..0e05ea031 100644
--- a/libhb/fifo.c
+++ b/libhb/fifo.c
@@ -681,6 +681,58 @@ void hb_buffer_move_subs( hb_buffer_t * dst, hb_buffer_t * src )
}
+hb_image_t * hb_buffer_to_image(hb_buffer_t *buf)
+{
+ hb_image_t *image = calloc(1, sizeof(hb_image_t));
+
+#if defined( SYS_DARWIN ) || defined( SYS_FREEBSD ) || defined( SYS_MINGW )
+ image->data = malloc( buf->size );
+#elif defined( SYS_CYGWIN )
+ /* FIXME */
+ image->data = malloc( buf->size + 17 );
+#else
+ image->data = memalign( 16, buf->size );
+#endif
+ if (image->data == NULL)
+ {
+ free(image);
+ return NULL;
+ }
+
+ image->format = buf->f.fmt;
+ image->width = buf->f.width;
+ image->height = buf->f.height;
+ memcpy(image->data, buf->data, buf->size);
+
+ int p;
+ uint8_t *data = image->data;
+ for (p = 0; p < 4; p++)
+ {
+ image->plane[p].data = data;
+ image->plane[p].width = buf->plane[p].width;
+ image->plane[p].height = buf->plane[p].height;
+ image->plane[p].stride = buf->plane[p].stride;
+ image->plane[p].height_stride = buf->plane[p].height_stride;
+ image->plane[p].size = buf->plane[p].size;
+ data += image->plane[p].size;
+ }
+ return image;
+}
+
+void hb_image_close(hb_image_t **_image)
+{
+ if (_image == NULL)
+ return;
+
+ hb_image_t * image = *_image;
+ if (image != NULL)
+ {
+ free(image->data);
+ free(image);
+ *_image = NULL;
+ }
+}
+
hb_fifo_t * hb_fifo_init( int capacity, int thresh )
{
hb_fifo_t * f;
diff --git a/libhb/hb.c b/libhb/hb.c
index e6036587f..e7c9c22bf 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -671,64 +671,124 @@ int hb_save_preview( hb_handle_t * h, int title, int preview, hb_buffer_t *buf )
return 0;
}
-hb_buffer_t * hb_read_preview( hb_handle_t * h, int title_idx, int preview )
+hb_buffer_t * hb_read_preview(hb_handle_t * h, hb_title_t *title, int preview)
{
FILE * file;
char filename[1024];
- hb_title_set_t *title_set;
- hb_title_t * title = NULL;
-
- title_set = hb_get_title_set(h);
-
- int ii;
- for (ii = 0; ii < hb_list_count(title_set->list_title); ii++)
- {
- title = hb_list_item( title_set->list_title, ii);
- if (title != NULL && title->index == title_idx)
- {
- break;
- }
- title = NULL;
- }
- if (title == NULL)
- {
- hb_error( "hb_read_preview: invalid title (%d)", title_idx );
- return NULL;
- }
-
- hb_get_tempory_filename( h, filename, "%d_%d_%d",
- hb_get_instance_id(h), title_idx, preview );
+ hb_get_tempory_filename(h, filename, "%d_%d_%d",
+ hb_get_instance_id(h), title->index, preview);
file = hb_fopen(filename, "rb");
- if( !file )
+ if (!file)
{
hb_error( "hb_read_preview: fopen failed (%s)", filename );
return NULL;
}
hb_buffer_t * buf;
- buf = hb_frame_buffer_init( AV_PIX_FMT_YUV420P, title->width, title->height );
+ buf = hb_frame_buffer_init(AV_PIX_FMT_YUV420P, title->width, title->height);
int pp, hh;
- for( pp = 0; pp < 3; pp++ )
+ for (pp = 0; pp < 3; pp++)
{
uint8_t *data = buf->plane[pp].data;
int stride = buf->plane[pp].stride;
int w = buf->plane[pp].width;
int h = buf->plane[pp].height;
- for( hh = 0; hh < h; hh++ )
+ for (hh = 0; hh < h; hh++)
{
- fread( data, w, 1, file );
+ fread(data, w, 1, file);
data += stride;
}
}
- fclose( file );
+ fclose(file);
return buf;
}
+hb_image_t* hb_get_preview2(hb_handle_t * h, int title_idx, int picture,
+ hb_ui_geometry_t *ui_geo, int deinterlace)
+{
+ char filename[1024];
+ hb_buffer_t * in_buf, * deint_buf = NULL, * preview_buf;
+ uint32_t swsflags;
+ AVPicture pic_in, pic_preview, pic_deint, pic_crop;
+ struct SwsContext * context;
+
+ int width = ui_geo->width * ui_geo->par.num / ui_geo->par.den;
+ int height = ui_geo->height;
+
+ swsflags = SWS_LANCZOS | SWS_ACCURATE_RND;
+
+ preview_buf = hb_frame_buffer_init(AV_PIX_FMT_RGB32, width, height);
+ hb_avpicture_fill( &pic_preview, preview_buf );
+
+ // Allocate the AVPicture frames and fill in
+
+ memset( filename, 0, 1024 );
+
+ hb_title_t * title;
+ title = hb_find_title_by_index(h, title_idx);
+ if (title == NULL)
+ {
+ hb_error( "hb_get_preview2: invalid title (%d)", title_idx );
+ return NULL;
+ }
+
+ in_buf = hb_read_preview( h, title, picture );
+ if ( in_buf == NULL )
+ {
+ return NULL;
+ }
+
+ hb_avpicture_fill( &pic_in, in_buf );
+
+ if (deinterlace)
+ {
+ // Deinterlace and crop
+ deint_buf = hb_frame_buffer_init( AV_PIX_FMT_YUV420P,
+ title->width, title->height );
+ hb_deinterlace(deint_buf, in_buf);
+ hb_avpicture_fill( &pic_deint, deint_buf );
+
+ av_picture_crop(&pic_crop, &pic_deint, AV_PIX_FMT_YUV420P,
+ ui_geo->crop[0], ui_geo->crop[2] );
+ }
+ else
+ {
+ // Crop
+ av_picture_crop(&pic_crop, &pic_in, AV_PIX_FMT_YUV420P,
+ ui_geo->crop[0], ui_geo->crop[2] );
+ }
+
+ // Get scaling context
+ context = hb_sws_get_context(
+ title->width - (ui_geo->crop[2] + ui_geo->crop[3]),
+ title->height - (ui_geo->crop[0] + ui_geo->crop[1]),
+ AV_PIX_FMT_YUV420P, width, height, AV_PIX_FMT_RGB32,
+ swsflags);
+
+ // Scale
+ sws_scale(context,
+ (const uint8_t* const *)pic_crop.data, pic_crop.linesize,
+ 0, title->height - (ui_geo->crop[0] + ui_geo->crop[1]),
+ pic_preview.data, pic_preview.linesize);
+
+ // Free context
+ sws_freeContext( context );
+
+ hb_image_t *image = hb_buffer_to_image(preview_buf);
+
+ // Clean up
+ hb_buffer_close( &in_buf );
+ hb_buffer_close( &deint_buf );
+ hb_buffer_close( &preview_buf );
+
+ return image;
+}
+
/**
* Create preview image of desired title a index of picture.
* @param h Handle to hb_handle_t.
@@ -759,7 +819,7 @@ void hb_get_preview( hb_handle_t * h, hb_job_t * job, int picture,
memset( filename, 0, 1024 );
- in_buf = hb_read_preview( h, title->index, picture );
+ in_buf = hb_read_preview( h, title, picture );
if ( in_buf == NULL )
{
return;
diff --git a/libhb/hb.h b/libhb/hb.h
index cad630650..2d32e1aef 100644
--- a/libhb/hb.h
+++ b/libhb/hb.h
@@ -68,9 +68,12 @@ int hb_detect_comb( hb_buffer_t * buf, int color_equal, int color_diff, int thre
// JJJ: title->job?
int hb_save_preview( hb_handle_t * h, int title, int preview,
hb_buffer_t *buf );
-hb_buffer_t * hb_read_preview( hb_handle_t * h, int title_idx, int preview );
+hb_buffer_t * hb_read_preview( hb_handle_t * h, hb_title_t *title,
+ int preview );
void hb_get_preview( hb_handle_t *, hb_job_t *, int,
uint8_t * );
+hb_image_t * hb_get_preview2(hb_handle_t * h, int title_idx, int picture,
+ hb_ui_geometry_t *ui_geo, int deinterlace);
void hb_set_anamorphic_size2(hb_geometry_t *src_geo,
hb_ui_geometry_t *ui_geo,
hb_geometry_t *result);
@@ -83,12 +86,13 @@ void hb_add_filter( hb_job_t * job, hb_filter_object_t * filter,
/* Handling jobs */
int hb_count( hb_handle_t * );
-hb_job_t * hb_job( hb_handle_t *, int );
+hb_job_t * hb_job( hb_handle_t *, int );
void hb_add( hb_handle_t *, hb_job_t * );
void hb_rem( hb_handle_t *, hb_job_t * );
-hb_job_t * hb_job_init_by_index( hb_handle_t *h, int title_index );
-hb_job_t * hb_job_init( hb_title_t * title );
+hb_title_t * hb_find_title_by_index( hb_handle_t *h, int title_index );
+hb_job_t * hb_job_init_by_index( hb_handle_t *h, int title_index );
+hb_job_t * hb_job_init( hb_title_t * title );
void hb_job_reset( hb_job_t * job );
void hb_job_close( hb_job_t ** job );
diff --git a/libhb/internal.h b/libhb/internal.h
index ed7eab367..c71b23ecd 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -106,7 +106,7 @@ struct hb_buffer_s
int fmt;
} f;
- struct plane
+ struct buffer_plane
{
uint8_t * data;
int stride;
@@ -163,6 +163,7 @@ hb_buffer_t * hb_buffer_dup( const hb_buffer_t * src );
int hb_buffer_copy( hb_buffer_t * dst, const hb_buffer_t * src );
void hb_buffer_swap_copy( hb_buffer_t *src, hb_buffer_t *dst );
void hb_buffer_move_subs( hb_buffer_t * dst, hb_buffer_t * src );
+hb_image_t * hb_buffer_to_image(hb_buffer_t *buf);
hb_fifo_t * hb_fifo_init( int capacity, int thresh );
int hb_fifo_size( hb_fifo_t * );