diff options
author | jstebbins <[email protected]> | 2014-07-29 18:40:38 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2014-07-29 18:40:38 +0000 |
commit | 6942656aeac26e63e87d8c1772ccec3e64b437e1 (patch) | |
tree | e82d337589c6bcfafe17963337f99ad6d41ec890 /libhb | |
parent | 56680a9b967772ca6eb9112ac6f2a9e9bbe7244b (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
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/common.c | 16 | ||||
-rw-r--r-- | libhb/common.h | 21 | ||||
-rw-r--r-- | libhb/fifo.c | 52 | ||||
-rw-r--r-- | libhb/hb.c | 122 | ||||
-rw-r--r-- | libhb/hb.h | 12 | ||||
-rw-r--r-- | libhb/internal.h | 3 |
6 files changed, 190 insertions, 36 deletions
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 * ); |