summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2012-06-25 07:49:25 +0000
committerjstebbins <[email protected]>2012-06-25 07:49:25 +0000
commitf08990395ec04f3f5edbe90d3cc38de2e857b47e (patch)
tree3d8b043f1666f715b8f1b4729ab8ef6271dc9ce1
parent63d4e3c48fc1d9ad0925c52afecd9d76d9a39bfb (diff)
bugfix branch: fix <mod8 problem with preview generation and deinterlace fast
If the source dimensions are less than mod 8 aligned, deinterlace fast will fail. Since deinterlace fast is used in preview generation, previews would fail if any deinterlaceing mode is enabled. This fix copies the source buffer into a buffer that has right and bottom padding enough to meet the mod 8 requirement. git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/0.9.x@4775 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/deinterlace.c50
-rw-r--r--libhb/hb.c60
2 files changed, 74 insertions, 36 deletions
diff --git a/libhb/deinterlace.c b/libhb/deinterlace.c
index bd51e9a77..50ebd7e25 100644
--- a/libhb/deinterlace.c
+++ b/libhb/deinterlace.c
@@ -582,8 +582,54 @@ int hb_deinterlace_work( hb_buffer_t * buf_in,
avpicture_fill( &pv->pic_out, pv->buf_out[0]->data,
pix_fmt, width, height );
- avpicture_deinterlace( &pv->pic_out, &pv->pic_in,
- pix_fmt, width, height );
+ if ( ( width & 7 ) || ( height & 7 ) )
+ {
+ // avpicture_deinterlace requires 8 pixel aligned dimensions
+ // so we are going to have to do some buffer copying
+ int aligned_width = ((width + 7) & ~7);
+ int aligned_height = ((height + 7) & ~7);
+ uint8_t * buf1, * buf2;
+ AVPicture pic_in, pic_out;
+ int i, p;
+
+ buf1 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P,
+ aligned_width, aligned_height ) );
+ buf2 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P,
+ aligned_width, aligned_height ) );
+ avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P,
+ aligned_width, aligned_height );
+ avpicture_fill( &pic_out, buf2, PIX_FMT_YUV420P,
+ aligned_width, aligned_height );
+ for (p = 0; p < 3; p++)
+ {
+ int h = !p ? height : height >> 1;
+ for (i = 0; i < h; i++)
+ {
+ memcpy(pic_in.data[p] + pic_in.linesize[p] * i,
+ pv->pic_in.data[p] + pv->pic_in.linesize[p] * i,
+ pv->pic_in.linesize[p]);
+ }
+ }
+ avpicture_deinterlace( &pic_out, &pic_in,
+ pix_fmt, aligned_width, aligned_height );
+ for (p = 0; p < 3; p++)
+ {
+ int h = !p ? height : height >> 1;
+ for (i = 0; i < h; i++)
+ {
+ memcpy(pv->pic_out.data[p] + pv->pic_out.linesize[p] * i,
+ pic_out.data[p] + pic_out.linesize[p] * i,
+ pv->pic_out.linesize[p]);
+ }
+ }
+ avpicture_free( &pic_in );
+ avpicture_free( &pic_out );
+ }
+ else
+ {
+ avpicture_deinterlace( &pv->pic_out, &pv->pic_in,
+ pix_fmt, width, height );
+ }
hb_buffer_copy_settings( pv->buf_out[0], buf_in );
diff --git a/libhb/hb.c b/libhb/hb.c
index efc1d8cc4..7055e5cf7 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -712,29 +712,26 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
hb_job_t * job = title->job;
char filename[1024];
FILE * file;
- uint8_t * buf1, * buf2, * buf3, * buf4, * pen;
+ uint8_t * buf1, * buf2, * buf3, * pen;
uint32_t swsflags;
- AVPicture pic_in, pic_preview, pic_deint, pic_crop, pic_scale;
+ AVPicture pic_in, pic_preview, pic_deint, pic_crop;
struct SwsContext * context;
- int i;
- int deint_width = ((title->width + 7) >> 3) << 3;
- int rgb_width = ((job->width + 7) >> 3) << 3;
+ int i, p;
+ int aligned_width = ((title->width + 7) & ~7);
+ int aligned_height = ((title->height + 7) & ~7);
int preview_size;
swsflags = SWS_LANCZOS | SWS_ACCURATE_RND;
- buf1 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height ) );
- buf2 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, deint_width, title->height ) );
- buf3 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, rgb_width, job->height ) );
- buf4 = av_malloc( avpicture_get_size( PIX_FMT_RGB32, rgb_width, job->height ) );
+ buf1 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, aligned_width, aligned_height ) );
+ buf2 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, aligned_width, aligned_height ) );
+ buf3 = av_malloc( avpicture_get_size( PIX_FMT_RGB32, job->width, job->height ) );
avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P,
- title->width, title->height );
+ aligned_width, aligned_height );
avpicture_fill( &pic_deint, buf2, PIX_FMT_YUV420P,
- deint_width, title->height );
- avpicture_fill( &pic_scale, buf3, PIX_FMT_YUV420P,
- rgb_width, job->height );
- avpicture_fill( &pic_preview, buf4, PIX_FMT_RGB32,
- rgb_width, job->height );
+ aligned_width, aligned_height );
+ avpicture_fill( &pic_preview, buf3, PIX_FMT_RGB32,
+ job->width, job->height );
// Allocate the AVPicture frames and fill in
@@ -750,13 +747,23 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
return;
}
- fread( buf1, avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height), 1, file );
+ for (p = 0; p < 3; p++)
+ {
+ int w = !p ? title->width : title->width >> 1;
+ int h = !p ? title->height : title->height >> 1;
+ pen = pic_in.data[p];
+ for (i = 0; i < h; i++)
+ {
+ fread( pen, w, 1, file );
+ pen += pic_in.linesize[p];
+ }
+ }
fclose( file );
if( job->deinterlace )
{
// Deinterlace and crop
- avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P, title->width, title->height );
+ avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P, aligned_width, aligned_height );
av_picture_crop( &pic_crop, &pic_deint, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
}
else
@@ -769,27 +776,13 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
context = hb_sws_get_context(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,
+ job->width, job->height, PIX_FMT_RGB32,
swsflags);
// Scale
sws_scale(context,
(const uint8_t* const *)pic_crop.data, pic_crop.linesize,
0, title->height - (job->crop[0] + job->crop[1]),
- pic_scale.data, pic_scale.linesize);
-
- // Free context
- sws_freeContext( context );
-
- // Get preview context
- context = hb_sws_get_context(rgb_width, job->height, PIX_FMT_YUV420P,
- rgb_width, job->height, PIX_FMT_RGB32,
- swsflags);
-
- // Create preview
- sws_scale(context,
- (const uint8_t* const *)pic_scale.data, pic_scale.linesize,
- 0, job->height,
pic_preview.data, pic_preview.linesize);
// Free context
@@ -799,13 +792,12 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture,
pen = buffer;
for( i = 0; i < job->height; i++ )
{
- memcpy( pen, buf4 + preview_size * i, 4 * job->width );
+ memcpy( pen, buf3 + preview_size * i, 4 * job->width );
pen += 4 * job->width;
}
// Clean up
avpicture_free( &pic_preview );
- avpicture_free( &pic_scale );
avpicture_free( &pic_deint );
avpicture_free( &pic_in );
}